2017-12-04 8 views
1

PythonでC拡張を書く方法を学びます。 ptest.pyカスタムPython拡張 - インポートエラー:未定義シンボル

Traceback (most recent call last): 
    File "ptest.py", line 1, in <module> 
    import euler_py as eul 
ImportError: /usr/local/lib/python3.6/site-packages/euler_py.cpython- 
36m-x86_64-linux-gnu.so: undefined symbol: problem_one 

を実行すると、次のエラーに実行している私は、この問題を結ぶいくつかのタイプであると仮定しています。

setup.py

sources = glob.glob('ext/*.c') 

euler = Extension(
    'euler_py', 
    include_dirs=['src'], 
    sources=sources, 
    extra_compile_args=['-std=c99'] 
) 

setup(
    name='euler_py', 
    version='0.1', 
    description='Project Euler Solutions', 
    ext_modules=[euler] 
) 

ptest.py

import euler_py as eul 

print(eul.problem_one(10)) 

基礎となる機能が/srcであると私は私の拡張子が/ext/euler_py.c

の下に示されているC.純粋にテストする test.cを書きました

ext/euler_py.c

#include <Python.h> 
#include "../src/euler.h" 

static char module_docstring[] = "Provides interface to Project Euler problems"; 

/* 
* Function implementations 
*/ 


static PyObject* euler_py_problem_one(PyObject *self, PyObject *args) 
{ 
    int max, result; 

    if (!PyArg_ParseTuple(args, "i", &max)) 
     return NULL; 

    result = problem_one(max); 

    return Py_BuildValue("i", result); 
} 
// END function implementations 

// Wire in functions to module 
static PyMethodDef module_methods[] = { 
     {"problem_one", euler_py_problem_one, METH_VARARGS, "Solution to problem 1"}, 
     {NULL, NULL, 0, NULL} 
}; 


// Module definition 
static struct PyModuleDef euler_py_module = { 
     PyModuleDef_HEAD_INIT, 
     "euler_py", 
     module_docstring, 
     -1, 
     module_methods 
}; 

// Module initialization function 
PyMODINIT_FUNC PyInit_euler_py(void) 
{ 
    return PyModule_Create(&euler_py_module); 
} 

Repoはhereです。私はlibrary_dirs & include_dirsExtension()開始と幸運で遊んだ。 Pythonバージョン3.6。もう一度見てください。レポが尋ねるオリジナルから変更されたためにリンクされ

EDIT

。以前と同じ魔法の他の3つの機能へのリンクを追加しました。

答えて

3

あなたはすべてのソースファイルを含めることを忘れ:

sources = glob.glob('ext/*.c') + glob.glob('src/*.c') 

あなたはsetup.py build -fvとC拡張ビルドの詳細を見ることができる:

$ python setup.py build -fv 
... 
clang -bundle -undefined dynamic_lookup build/temp.macosx-10.13-x86_64-3.6/ext/euler_py.o build/temp.macosx-10.13-x86_64-3.6/src/euler.o build/temp.macosx-10.13-x86_64-3.6/src/helpers.o -o build/lib.macosx-10.13-x86_64-3.6/euler_py.cpython-36m-darwin.so 

helpers.oeuler.o正しくリンク。

+0

'include_dirs'を削除することもできますし、' .h'ファイルをどのように見つけられるのでしょうか? – Adam

+0

@Adam私はそれが依存すると思う。 '#include 'または '#include" euler.h "'を書くと 'include_dirs'が必要です。あなたが '#include" ../ src/euler.h "'を使用した場合、あなたはしません。私は元のバージョンを好む。 [#includeについてもっと読む](http://en.cppreference.com/w/cpp/preprocessor/include) – georgexsh

+0

ええ、私のIDEは自動的に相対インポートをそこに置くと思う(CLion)。私は単にユーラーを好みます。 h "' 'vs' "../ src/euler.h" – Adam

関連する問題