2010-07-17 2 views
3

파이썬 확장 모듈은 동적 라이브러리 일 뿐이므로 파이썬 확장 모듈을 동적으로 링크 할 수 있다고 가정합니다. 문제는 Windows Python Extensions에 .dll 대신 .pyd 확장이 주어 지므로 설치 스크립트를 실행할 때 distutils를 링크 할 수 없습니다. 파이썬 확장이 .so 파일 확장자를 사용하기 때문에 이것은 유닉스에서 문제라고 생각하지 않는다.파이썬 확장 (.pyd)을 다른 확장 모듈에 동적으로 연결하기

나는 foo.pyd으로 링크해야하는 확장자 bar.pyd이 있다고 가정한다. 기본적으로 설치 스크립트에서 수행 한 작업은 다음과 같습니다.

from distutils.core import setup, Extension 

foo = Extension("foo", sources=["foo.c"]) 
bar = Extension("bar", libraries=["foo"], sources=["bar.c"]) 
setup(ext_modules=[foo, bar]) 

지금까지는 작동하지 않습니다. 이것은 가능한가? 나는 그렇다고 생각하지만 온라인에서 아무것도 찾을 수 없었습니다. 저는 Windows에서 MinGW를 사용하고 있습니다 만, 다른 MSVC++ 및 다른 시스템에서도이 기능을 사용하고 싶습니다.

편집 : 이전에, 내가 foo이 확장의 extra_objects 옵션으로 컴파일 할 때 (foo.o가) (나 bar 모든 foo 기호 프로토 타입을 정의 된 경우에만 동작 것) 생성 된 오브젝트 파일을 전달하여이 문제를 해결 :

bar = Extension("bar", sources=["bar.c"], extra_objects=["build/.../foo.o"] 

이것은 올바른 해결책은 아니지만 효과가있었습니다. 동적 연결을 잘 이해하지 못하기 때문에 올바른 방법 일 수 있습니다. 그것은 매우 잘못 생각합니다.

다음, 나는 그것을 가져 오기 라이브러리 컴파일하기 위해 GCC 일부 명시 적으로 인수를 전달하려고 :

foo = Extension("foo", sources=["foo.c"], extra_compile_args=["-Wl,--out-implib,foo.lib,--export-all-symbols"]) 

을 그리고 나는 새로운 가져 오기 라이브러리에 bar를 연결 :

bar = Extension("bar", libraries=["foo"], sources=["bar.c"]) 

이없이 컴파일 불만 사항이 있었지만 일부 기호와 관련된 문제가있었습니다 (구체적으로 PyTypeObject은 에 다시 정의 된 것으로 보이는 foo에 있습니다.) PyTypeObject이 필요합니다. 두 모듈 모두에서 동일한 정의를 참조하십시오.).

편집 2 : 그래서 문제를 골라 내었습니다. 가져 오기 라이브러리에 대해 빌드하고 연결 한 후에 기능 심볼이 올바르게 내보내졌지만 PyTypeObject이 다시 선언되었습니다. fooPyTypeOject Foo_Type이 있다고 가정합니다. bar.c의 상단이

PyTypeObject __declspec(dllexport) Foo_Type; 

와 : 둘 다 foo.cbar.c에 포함 foo.h, 그것을 선언 : 나는 그것을 꺼내

PyTypeObject Foo_Type; 

foo.c의 상단이를 넣어 :

PyTypeObject __declspec(dllimport) Foo_Type; 

문제가 해결되었습니다. 그런 다음 Foo_Type을 foobar에서 사용할 수 있으며 Foo_Type과 동일한 정의를 참조했습니다. 문제는 이것이 비 Windows 시스템에서 작동하지 않는다는 것입니다. 내가 방금 __declspec을 꺼내면 다른 시스템에서도 잘 작동한다고 가정합니다.

답변

1

일반적인 파이썬 import mechanisms을 사용하는 경우 다른 확장자와 연결할 필요가 없습니다. 다른 확장 기능에서 함수를 호출하는 경우 아마도 헤더 파일을 보류했기 때문에 아마도 DLL에서 가져 오기 lib를 생성해야 연결될 수 있습니다. 에서

+0

모두 내 프로젝트의 일부입니다, 그래서 파이썬 가져 오기 메커니즘을 사용하는 대신 그들 사이에 연결하고 싶습니다. 나는이 점에서 꽤 새로운데, 그래서 import lib를 생성하는 방법을 잘 모르겠습니다. 이것에 대해 좀 밝힐 수 있습니까? –

0
from distutils.core import Extension as cExtension 
from pyd.support import setup, Extension 

module1 = Extension("x", sources = ['xclass.c']) 
module2 = Extension("y", sources = ['hello.d'], build_deimos=True) 

setup(
    name = "x", 
    version = '1.0', 
    description = "eat a taco", 
    ext_modules = [ 
     module1, 
     module2 
    ] 
); 

:이 확장 모듈의 http://pyd.readthedocs.io/en/latest/distutils.html

+0

이것은 D 프로그래밍 언어와 아무 관련이 없습니다. –

관련 문제