24

Cython は初めてで、Cython を使用して C/C++ 静的ライブラリをラップしようとしています。以下のように簡単な例を作りました。

Test.h:

#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
)

私が電話した:

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
llMain@12 --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

libraries=['test']の代わりにも使ってみましたlibraries=['libtest']。それは私に同じエラーを与えました。

これについての手がかりはありますか?

4

3 に答える 3

27

C++ コードがラッパーによってのみ使用される場合、別のオプションとして、次のようにセットアップで .cpp ファイルをコンパイルすることができます。

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
)

静的ライブラリにリンクするには、次のようにextra_objects引数を使用する必要があります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
)
于 2010-01-21T00:15:55.997 に答える
5

ファイルが期待どおりに機能していませTest.pyxん。このprint add(2,3)行はC++ 関数を呼び出しません。add()そのためには、ラッパー関数を明示的に作成する必要があります。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)

詳細については、Cython のドキュメントを参照してください。

于 2014-01-29T19:23:55.617 に答える
2

この特定の問題は、正しい場所を指定することで解決できると思いますlibrary_dirs(実際libtest.a を配置した場所 - 明らかに見つからない) が、別の問題が発生すると思いますextern "C"。そのため、関数の名前は C++ コンパイラによって「マングル」されているため (libtest.a からエクスポートされた名前を見てください!)、C++ 以外の他の言語 (C、Cython などを含む) には問題があります。それらに到達します。修正は、それらを として宣言することextern "C"です。

于 2010-01-20T23:49:35.323 に答える