【问题标题】:Cython cannot find the declared function from cimported moduleCython 无法从 cimported 模块中找到声明的函数
【发布时间】:2018-03-17 21:58:03
【问题描述】:

系统:Mac OS 10.12.6。 Python:来自 Anconda3 的 Python 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 代码。

【问题讨论】:

  • 问题的根源可能是 pdx 和 pyx 文件具有相同的名称。尝试将 pdx-file 命名为 CLexActivator...

标签: cython cythonize


【解决方案1】:

我无法重现您的确切错误,但我认为问题在于您正在覆盖 SetProductFile

pxdpyx 文件同名的文件会自动导入 - 相当于from LexActivator cimport *。因此,您不需要cimport LexActivator。出现问题是因为 def 函数 SetProductFile 与您的 C 函数同名(这让 Cython 感到困惑 - 我收到的是警告而不是错误)

我也会避免在 Cython 和 C 文件中使用相同的名称。 Cython 编译会生成一个LexActivator.c 文件,在某些情况下会生成一个LexActivator.h 文件,因此如果您自己的 C 文件具有相同的名称,很容易被覆盖。


总的来说,你有两个选择:

  1. 重命名 Python def 函数(并删除 cimport LexActivator

  2. (如@ead 建议的那样)将您的pxd 重命名为其他名称,执行cimport SomethingElse,然后您的SetProductFile 不会与名称冲突。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-09-30
    • 1970-01-01
    • 2019-12-29
    • 2017-08-13
    • 2019-01-18
    • 2016-02-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多