Cython 设置外部变量导致访问冲突
Cython setting external variable causes access violation
我正在尝试使用 cython 包装外部库。外部库的部分接口要求我设置从 dll 导出的外部变量的成员,但我收到访问冲突错误:
Process finished with exit code -1073741819 (0xC0000005)
我将 Cython 与 Python 2.7 和来自 http://www.microsoft.com/en-us/download/details.aspx?id=44266 的编译器套件一起使用。一切都在使用 setuptools 正确编译和链接。
以下 .pyx 代码包含问题:
import numpy as np
cimport numpy as cnp
ctypedef float real32_T
ctypedef struct ExtU_ST_TopLevel_MWL_T:
real32_T GroundSpeed
cdef extern from 'ST_TopLevel_MWL.h':
void ST_TopLevel_MWL_initialize()
void ST_TopLevel_MWL_step()
void ST_TopLevel_MWL_terminate()
ExtU_ST_TopLevel_MWL_T ST_TopLevel_MWL_U
def ST_TopLevel_MWL_batch_run(cnp.ndarray[cnp.double_t, ndim=1, mode='c'] ground_speed not None):
global ST_TopLevel_MWL_U
ST_TopLevel_MWL_initialize()
print('0x%x' % <unsigned long long>&ST_TopLevel_MWL_U)
print('0x%x' % <unsigned long long>&ST_TopLevel_MWL_U.GroundSpeed)
print('%f' % ST_TopLevel_MWL_U.GroundSpeed)
# The following line results in the access violation
ST_TopLevel_MWL_U.GroundSpeed = <float>0.0
print('%f' % ST_TopLevel_MWL_U.GroundSpeed)
ST_TopLevel_MWL_terminate()
ST_TopLevel_MWL_U.GroundSpeed = <float>0.0
行导致访问冲突。如果删除该行,我不会遇到访问冲突,但是,当然,如果我无法设置此变量,我将无法使用该 dll。
我相信 setuptools 正在静态链接一个负责动态加载 dll (.dll) 的库 (.lib),但我完全不知道它的机制,所以我很难找到根本原因。
我尝试与之交互的 dll 是使用 'ert_shrlib.tlc' 目标和 'Microsoft Windows SDK v7.1 | nmake (64-bit Windows)' 工具链从 Matlab Simulink 嵌入式编码器生成和构建的。
问题是头文件'ST_TopLevel_MWL.h'没有声明使用__declspec(dllimport)
导入dll的变量
一个msdn article给出了足够的细节来解释它。以下是摘录:
"However, you must use __declspec(dllimport) in order to import variables used in a DLL."
Matlab Simulink Embedded Coder 'ert_shrlib.tlc' 目标使用 .DEF 文件公开导出的过程和变量。它在头文件中直接使用 extern ExtU_ST_TopLevel_MWL_T ST_TopLevel_MWL_U;
。当用于编译 dll 的同一个头文件也用于事物的导入端的编译时,缺少的 __declspec(dllimport)
会导致构建的代码引用杂草中某处的幻像变量而不是导出的变量从 dll。这会导致访问冲突崩溃。
编辑头文件,将“extern
”替换为“extern __declspec(dllimport)
”即可解决问题。
这是另一个有用的 link,它解释了来自 Matlab Central 的问题:How do I call a DLL created from Simulink model in a Visual Studio application?
我正在尝试使用 cython 包装外部库。外部库的部分接口要求我设置从 dll 导出的外部变量的成员,但我收到访问冲突错误:
Process finished with exit code -1073741819 (0xC0000005)
我将 Cython 与 Python 2.7 和来自 http://www.microsoft.com/en-us/download/details.aspx?id=44266 的编译器套件一起使用。一切都在使用 setuptools 正确编译和链接。
以下 .pyx 代码包含问题:
import numpy as np
cimport numpy as cnp
ctypedef float real32_T
ctypedef struct ExtU_ST_TopLevel_MWL_T:
real32_T GroundSpeed
cdef extern from 'ST_TopLevel_MWL.h':
void ST_TopLevel_MWL_initialize()
void ST_TopLevel_MWL_step()
void ST_TopLevel_MWL_terminate()
ExtU_ST_TopLevel_MWL_T ST_TopLevel_MWL_U
def ST_TopLevel_MWL_batch_run(cnp.ndarray[cnp.double_t, ndim=1, mode='c'] ground_speed not None):
global ST_TopLevel_MWL_U
ST_TopLevel_MWL_initialize()
print('0x%x' % <unsigned long long>&ST_TopLevel_MWL_U)
print('0x%x' % <unsigned long long>&ST_TopLevel_MWL_U.GroundSpeed)
print('%f' % ST_TopLevel_MWL_U.GroundSpeed)
# The following line results in the access violation
ST_TopLevel_MWL_U.GroundSpeed = <float>0.0
print('%f' % ST_TopLevel_MWL_U.GroundSpeed)
ST_TopLevel_MWL_terminate()
ST_TopLevel_MWL_U.GroundSpeed = <float>0.0
行导致访问冲突。如果删除该行,我不会遇到访问冲突,但是,当然,如果我无法设置此变量,我将无法使用该 dll。
我相信 setuptools 正在静态链接一个负责动态加载 dll (.dll) 的库 (.lib),但我完全不知道它的机制,所以我很难找到根本原因。
我尝试与之交互的 dll 是使用 'ert_shrlib.tlc' 目标和 'Microsoft Windows SDK v7.1 | nmake (64-bit Windows)' 工具链从 Matlab Simulink 嵌入式编码器生成和构建的。
问题是头文件'ST_TopLevel_MWL.h'没有声明使用__declspec(dllimport)
一个msdn article给出了足够的细节来解释它。以下是摘录:
"However, you must use __declspec(dllimport) in order to import variables used in a DLL."
Matlab Simulink Embedded Coder 'ert_shrlib.tlc' 目标使用 .DEF 文件公开导出的过程和变量。它在头文件中直接使用 extern ExtU_ST_TopLevel_MWL_T ST_TopLevel_MWL_U;
。当用于编译 dll 的同一个头文件也用于事物的导入端的编译时,缺少的 __declspec(dllimport)
会导致构建的代码引用杂草中某处的幻像变量而不是导出的变量从 dll。这会导致访问冲突崩溃。
编辑头文件,将“extern
”替换为“extern __declspec(dllimport)
”即可解决问题。
这是另一个有用的 link,它解释了来自 Matlab Central 的问题:How do I call a DLL created from Simulink model in a Visual Studio application?