根據documentation,可以使用從Cython生成的C頭文件。我按照Hello World
的例子沒有問題,現在我想嘗試一些不同的東西。我想使用公共聲明來使用自定義方法。我的代碼結構如下:使用Cython生成的頭文件
- hello.pyx
- setup.py
- 的main.c
hello.pyx
cdef public void say_hello():
print("Hello World")
setup.py
from distutils.core import setup
from distutils.extension import Extension
from Cython.Distutils import build_ext
ext_modules = [
Extension("hello", ["hello.pyx", "main.c"]),
]
setup(
name='Hello app',
cmdclass={'build_ext': build_ext},
ext_modules=ext_modules
)
的main.c
#include "hello.h"
int main(void){
say_hello();
}
的main.c
充當測試文件以驗證say_hello()
方法按預期工作。 構建設置文件python3 setup.py build_ext
會生成以下輸出。
running build_ext
skipping 'hello.c' Cython extension (up-to-date)
building 'hello' extension
x86_64-linux-gnu-gcc -pthread -DNDEBUG -g -fwrapv -O2 -Wall -Wstrict-prototypes -g -fstack-protector-strong -Wformat -Werror=format-security -Wdate-time -D_FORTIFY_SOURCE=2 -fPIC -I/usr/include/python3.5m -c hello.c -o build/temp.linux-x86_64-3.5/hello.o
x86_64-linux-gnu-gcc -pthread -DNDEBUG -g -fwrapv -O2 -Wall -Wstrict-prototypes -g -fstack-protector-strong -Wformat -Werror=format-security -Wdate-time -D_FORTIFY_SOURCE=2 -fPIC -I/usr/include/python3.5m -c main.c -o build/temp.linux-x86_64-3.5/main.o
In file included from main.c:1:0:
hello.h:26:1: error: unknown type name ‘PyMODINIT_FUNC’
PyMODINIT_FUNC inithello(void);
^
error:
command 'x86_64-linux-gnu-gcc' failed with exit status 1
的hello.h文件包含以下
/* Generated by Cython 0.25.2 */
#ifndef __PYX_HAVE__hello
#define __PYX_HAVE__hello
#ifndef __PYX_HAVE_API__hello
#ifndef __PYX_EXTERN_C
#ifdef __cplusplus
#define __PYX_EXTERN_C extern "C"
#else
#define __PYX_EXTERN_C extern
#endif
#endif
#ifndef DL_IMPORT
#define DL_IMPORT(_T) _T
#endif
__PYX_EXTERN_C DL_IMPORT(void) say_hello(void);
#endif /* !__PYX_HAVE_API__hello */
#if PY_MAJOR_VERSION < 3
PyMODINIT_FUNC inithello(void); // <-- Line 26
#else
PyMODINIT_FUNC PyInit_hello(void);
#endif
#endif /* !__PYX_HAVE__hello */
據我瞭解,似乎在GCC不能夠得到的Python的正確版本(我使用Python 3.5)。有什麼辦法可以設置嗎?另外,如果確實如此,當我運行python3 setup.py build_ext
命令時,爲什麼不將鏈接到?
我沒有太多的C經驗,所以我可能會錯過一些東西。
感謝您的回答@ead,找到標誌的提示非常有用。 唉,在'main.c'的編譯過程中,我得到了方法'inithello()'的隱式聲明警告,後來在我嘗試鏈接時拋出一個錯誤「未定義的inithello引用」。 使用Python2.7很好! – BitWhyz
@BitWhyz通過查看hello.h代碼,我認爲你應該在Python3中使用'PyInit_hello()'而不是'inithello()'。 – ead
它的工作!謝謝。我不明白爲什麼文檔沒有提到這一點。我會很感激挖掘更多的好資源。 – BitWhyz