2010-01-20 4 views
16

저는 Cython을 처음 접했고 Cython을 사용하여 C/C++ 정적 라이브러리를 래핑했습니다. 나는 다음과 같이 간단한 예를 만들었다. Test.hCython으로 랩 C++ lib

:

#ifndef TEST_H 
#define TEST_H 

int add(int a, int b); 
int multipy(int a, int b); 

#endif 

Test.cpp에

#include "test.h" 
int add(int a, int b) 
{ 
    return a+b; 

} 

int multipy(int a, int b) 
{ 
    return a*b; 
} 

은 그럼 컴파일하고 구축 g ++를 사용했다.

g++ -c test.cpp -o libtest.o 
ar rcs libtest.a libtest.o 

이제 libtest.a라는 정적 라이브러리가 생겼습니다.

Test.pyx :

cdef extern from "test.h": 
     int add(int a,int b) 
     int multipy(int a,int b) 

print add(2,3) 

Setup.py :

from distutils.core import setup 
from distutils.extension import Extension 
from Cython.Distutils import build_ext 

ext_modules = [Extension("test", 
        ["test.pyx"], 
        language='c++', 
        include_dirs=[r'.'], 
        library_dirs=[r'.'], 
        libraries=['libtest'] 
        )] 

setup(
    name = 'test', 
    cmdclass = {'build_ext': build_ext}, 
    ext_modules = ext_modules 
) 

의 I라는 :

python setup.py build_ext --compiler=mingw32 --inplace 

출력했다 :

running build_ext 
cythoning test.pyx to test.cpp 
building 'test' extension 
creating build 
creating build\temp.win32-2.6 
creating build\temp.win32-2.6\Release 
C:\Program Files\pythonxy\mingw\bin\gcc.exe -mno-cygwin -mdll -O -Wall -I. -IC:\ 
Python26\include -IC:\Python26\PC -c test.cpp -o build\temp.win32-2.6\Release\test.o 
writing build\temp.win32-2.6\Release\test.def 
C:\Program Files\pythonxy\mingw\bin\g++.exe -mno-cygwin -mdll -static --entry _D 
[email protected] --output-lib build\temp.win32-2.6\Release\libtest.a --def build\temp.w 
in32-2.6\Release\test.def -s build\temp.win32-2.6\Release\test.o -L. -LC:\Python 
26\libs -LC:\Python26\PCbuild -ltest -lpython26 -lmsvcr90 -o test.pyd 
g++: build\temp.win32-2.6\Release\libtest.a: No such file or directory 
error: command 'g++' failed with exit status 1 

또한 라이브러리 = [ 'libtest'] 대신 라이브러리 = [ 'test']를 사용하려고했습니다. 그것은 나에게 같은 오류를 주었다.

그에 대한 단서가 있습니까?

감사합니다.

답변

2

나는 당신이 (당신이 실제로 하여 어느을 넣어 - 분명히 발견하기 아니에요) 권리 library_dirs를 지정하여이 특정 문제를 해결할 수 있다고 생각하지만, 난 당신이 또 다른 문제가있는 것 다음 생각 - 귀하의 항목을 포인트가 extern "C"으로 올바르게 선언되지 않았기 때문에 함수 이름이 C++ 컴파일러에 의해 "맹 글링"되었습니다 (libtest.a에서 내 보낸 이름을 보면 알 수 있습니다!), C++을 제외한 다른 모든 언어 (C , Cython 등)에 문제가 생길 수 있습니다. 수정 된 내용은 extern "C"으로 선언됩니다. 당신이 extra_objects를 사용할 필요가

from distutils.core import setup 
from distutils.extension import Extension 
from Cython.Distutils import build_ext 

ext_modules = [Extension("test", 
        ["test.pyx", "test.cpp"], 
        language='c++', 
        )] 

setup(
    name = 'test', 
    cmdclass = {'build_ext': build_ext}, 
    ext_modules = ext_modules 
) 

를 정적 라이브러리에 연결하는 경우 : 당신의 C++ 코드에만 랩퍼가 사용되는 경우

+0

어디에서 extern "C"를 선언해야합니까?그러나, 문제는 지금 빌드가 함수 대신 add() 또는 mulitpy() 중 하나 대신 libtest.a를 찾지 못한다고 불평한다는 것입니다. 그래서 이것이 효과가 있을지 확신하지 못합니다. 'build \ temp.win32-2.6 \ Release'에는 libtest.a가 없다는 것이 나에게 이상하다. Cython 자체에서 생성 한 빌드 폴더가 아닌가요? 왜 Cython은 libtest.a를 찾으려고 했습니까? –

+0

'extern "C"'는'.h'의 함수 선언에 들어가며, 잘못된'library_dirs'을 고친 후에 직면하게 될 다음 문제가 있습니다 (라이브러리는 현재 디렉토리에 있습니다. "그리고'Release'는 컴파일러/링커가 라이브러리를 찾을 때 현재 디렉토리가됩니다). –

23

또 다른 옵션은 설정이 다음과 같이 당신의 .cpp 파일을 컴파일 할 수 있도록하는 것입니다 당신의 Extension의 인수 :

from distutils.core import setup 
from distutils.extension import Extension 
from Cython.Distutils import build_ext 

ext_modules = [Extension("test", 
        ["test.pyx"], 
        language='c++', 
        extra_objects=["libtest.a"], 
        )] 

setup(
    name = 'test', 
    cmdclass = {'build_ext': build_ext}, 
    ext_modules = ext_modules 
) 
+1

아니요, 테스트를 위해서만 'test.cpp'를 만들었습니다. 실제 프로젝트에는 헤드 파일과 정적 라이브러리 만 있습니다. –

+3

당신이 원하는 것은 extra_objects 옵션, 편집 된 대답 인 것 같습니다. –

+0

@zyq 그래서 .so 파일이 만들어지면 어떻게 계속할까요? – PascalVKooten

4

귀하의 Test.pyx 파일은 당신이 무엇을 기대하고 있지 않습니다. print add(2,3) 라인 add() C++ 함수를 호출하지 않습니다.; 이를 수행하기 위해 명시 적으로 랩퍼 함수를 ​​작성해야합니다. Cython은 자동으로 래퍼를 생성하지 않습니다.

cdef extern from "test.h": 
     int _add "add"(int a,int b) 
     int _multiply "multiply"(int a,int b) 

def add(a, b): 
    return _add(a, b) 

def multiply(a, b): 
    return _multiply(a, b) 

print add(2, 3) 

당신은 사이 썬의 documentation 자세한 내용을 볼 수 있습니다 :이 같은

뭔가 당신이 원하는 아마.