Cython 无法从导入的模块中找到声明的函数
Cython cannot find the declared function from cimported module
系统:Mac OS 10.12.6。
Python:Python 来自 Anoconda3 的 3.5.2。
Cython==0.28
我正在尝试为静态 C++ 库编写包装器。这是头文件的一部分。
/* LexActivator.h */
#pragma once
#include <stdint.h>
#ifdef _WIN32
#include <windows.h>
#ifdef LEXACTIVATOR_EXPORTS
#ifdef LEXACTIVATOR__STATIC
#define LEXACTIVATOR_API extern "C"
#else
#define LEXACTIVATOR_API extern "C" __declspec(dllexport)
#endif
#else
#ifdef __cplusplus
#ifdef LEXACTIVATOR_STATIC
#define LEXACTIVATOR_API extern "C"
#else
#define LEXACTIVATOR_API extern "C" __declspec(dllimport)
#endif
#else
#ifdef LEXACTIVATOR_STATIC
#define LEXACTIVATOR_API
#else
#define LEXACTIVATOR_API __declspec(dllimport)
#endif
#endif
#endif
#if defined(USE_STDCALL_DLL) && !defined(LEXACTIVATOR_STATIC)
#define LA_CC __stdcall
#else
#define LA_CC __cdecl
#endif
typedef const wchar_t* CSTRTYPE;
typedef wchar_t* STRTYPE;
#else
#define LA_CC
typedef int32_t HRESULT;
#if __GNUC__ >= 4
#ifdef __cplusplus
#define LEXACTIVATOR_API extern "C" __attribute__((visibility("default")))
#else
#define LEXACTIVATOR_API __attribute__((visibility("default")))
#endif
#else
#ifdef __cplusplus
#define LEXACTIVATOR_API extern "C"
#else
#define LEXACTIVATOR_API
#endif
#endif
typedef const char* CSTRTYPE;
typedef char* STRTYPE;
#endif
#define LA_USER ((uint32_t)1)
#define LA_SYSTEM ((uint32_t)2)
#define LA_V_TRIAL ((uint32_t)1)
#define LA_UV_TRIAL ((uint32_t)2)
LEXACTIVATOR_API HRESULT LA_CC SetProductFile(CSTRTYPE filePath);
这是 Cython 的 pxd
文件的一部分。
from libc.stdint cimport *
cdef extern from "LexActivator.h":
ctypedef int32_t HRESULT
ctypedef const char* CSTRTYPE
ctypedef char* STRTYPE
uint32_t LA_USER = 1
uint32_t LA_SYSTEM = 2
uint32_t LA_V_TRIAL = 1
uint32_t LA_UV_TRIAL = 2
HRESULT SetProductFile(CSTRTYPE filePath)
然后我写了一个简单的 pyx
文件用于测试。
cimport LexActivator
def SetProductFile(filePath):
cdef bytes py_bytes = filePath.encode()
cdef const char* c_string = py_bytes
cdef int32_t status = LexActivator.SetProductFile(c_string)
print(status)
return status
安装文件
from distutils.core import setup
from distutils.extension import Extension
from Cython.Build import cythonize
ext_modules=[
Extension("LexActivator",
sources=["LexActivator.pyx"],
language='c++',
extra_objects=["libLexActivator.a"],
)
]
setup(
name = "LexActivator",
ext_modules = cythonize(ext_modules)
)
运行python setup.py build_ext --inplace
。
Error compiling Cython file:
------------------------------------------------------------
...
cimport LexActivator
def SetProductFile(filePath):
cdef bytes py_bytes = filePath.encode()
cdef const char* c_string = py_bytes
cdef int32_t status = LexActivator.SetProductFile(c_string)
^
------------------------------------------------------------
LexActivator.pyx:7:38: cimported module has no attribute 'SetProductFile'
PS:我已经成功地用 Xcode 完成了这个,仅用于 c 代码。
我无法重现您的确切错误,但我认为问题在于您正在覆盖 SetProductFile
。
pxd
与 pyx
文件同名的文件会自动导入 - 等同于 from LexActivator cimport *
。因此,您不需要 cimport LexActivator
。出现问题是因为 def
函数 SetProductFile
与您的 C 函数同名(这让 Cython 感到困惑 - 我收到的是警告而不是错误)
我也会避免使用您的 Cython 和 C 文件中的相同名称。 Cython编译生成LexActivator.c
文件,有的情况下生成LexActivator.h
文件,所以自己的C文件重名很容易被覆盖
总之,您有两个选择:
重命名您的 Python def
函数(并删除 cimport LexActivator
)
(如@ead 所建议)将您的 pxd
重命名为其他名称,执行 cimport SomethingElse
然后您的 SetProductFile
将不会与名称冲突。
系统:Mac OS 10.12.6。 Python:Python 来自 Anoconda3 的 3.5.2。 Cython==0.28
我正在尝试为静态 C++ 库编写包装器。这是头文件的一部分。
/* LexActivator.h */
#pragma once
#include <stdint.h>
#ifdef _WIN32
#include <windows.h>
#ifdef LEXACTIVATOR_EXPORTS
#ifdef LEXACTIVATOR__STATIC
#define LEXACTIVATOR_API extern "C"
#else
#define LEXACTIVATOR_API extern "C" __declspec(dllexport)
#endif
#else
#ifdef __cplusplus
#ifdef LEXACTIVATOR_STATIC
#define LEXACTIVATOR_API extern "C"
#else
#define LEXACTIVATOR_API extern "C" __declspec(dllimport)
#endif
#else
#ifdef LEXACTIVATOR_STATIC
#define LEXACTIVATOR_API
#else
#define LEXACTIVATOR_API __declspec(dllimport)
#endif
#endif
#endif
#if defined(USE_STDCALL_DLL) && !defined(LEXACTIVATOR_STATIC)
#define LA_CC __stdcall
#else
#define LA_CC __cdecl
#endif
typedef const wchar_t* CSTRTYPE;
typedef wchar_t* STRTYPE;
#else
#define LA_CC
typedef int32_t HRESULT;
#if __GNUC__ >= 4
#ifdef __cplusplus
#define LEXACTIVATOR_API extern "C" __attribute__((visibility("default")))
#else
#define LEXACTIVATOR_API __attribute__((visibility("default")))
#endif
#else
#ifdef __cplusplus
#define LEXACTIVATOR_API extern "C"
#else
#define LEXACTIVATOR_API
#endif
#endif
typedef const char* CSTRTYPE;
typedef char* STRTYPE;
#endif
#define LA_USER ((uint32_t)1)
#define LA_SYSTEM ((uint32_t)2)
#define LA_V_TRIAL ((uint32_t)1)
#define LA_UV_TRIAL ((uint32_t)2)
LEXACTIVATOR_API HRESULT LA_CC SetProductFile(CSTRTYPE filePath);
这是 Cython 的 pxd
文件的一部分。
from libc.stdint cimport *
cdef extern from "LexActivator.h":
ctypedef int32_t HRESULT
ctypedef const char* CSTRTYPE
ctypedef char* STRTYPE
uint32_t LA_USER = 1
uint32_t LA_SYSTEM = 2
uint32_t LA_V_TRIAL = 1
uint32_t LA_UV_TRIAL = 2
HRESULT SetProductFile(CSTRTYPE filePath)
然后我写了一个简单的 pyx
文件用于测试。
cimport LexActivator
def SetProductFile(filePath):
cdef bytes py_bytes = filePath.encode()
cdef const char* c_string = py_bytes
cdef int32_t status = LexActivator.SetProductFile(c_string)
print(status)
return status
安装文件
from distutils.core import setup
from distutils.extension import Extension
from Cython.Build import cythonize
ext_modules=[
Extension("LexActivator",
sources=["LexActivator.pyx"],
language='c++',
extra_objects=["libLexActivator.a"],
)
]
setup(
name = "LexActivator",
ext_modules = cythonize(ext_modules)
)
运行python setup.py build_ext --inplace
。
Error compiling Cython file:
------------------------------------------------------------
...
cimport LexActivator
def SetProductFile(filePath):
cdef bytes py_bytes = filePath.encode()
cdef const char* c_string = py_bytes
cdef int32_t status = LexActivator.SetProductFile(c_string)
^
------------------------------------------------------------
LexActivator.pyx:7:38: cimported module has no attribute 'SetProductFile'
PS:我已经成功地用 Xcode 完成了这个,仅用于 c 代码。
我无法重现您的确切错误,但我认为问题在于您正在覆盖 SetProductFile
。
pxd
与 pyx
文件同名的文件会自动导入 - 等同于 from LexActivator cimport *
。因此,您不需要 cimport LexActivator
。出现问题是因为 def
函数 SetProductFile
与您的 C 函数同名(这让 Cython 感到困惑 - 我收到的是警告而不是错误)
我也会避免使用您的 Cython 和 C 文件中的相同名称。 Cython编译生成LexActivator.c
文件,有的情况下生成LexActivator.h
文件,所以自己的C文件重名很容易被覆盖
总之,您有两个选择:
重命名您的 Python
def
函数(并删除cimport LexActivator
)(如@ead 所建议)将您的
pxd
重命名为其他名称,执行cimport SomethingElse
然后您的SetProductFile
将不会与名称冲突。