c++ - 从 Cython 设置 C++ 外部变量的值
问题描述
在我的项目中,我使用 Cython 包装了一些 C++ 代码(我可以完全控制),以便能够从 Python 调用 C++ 功能。
在其中一个 C++ 头文件中,我想使用“extern”关键字来定义(但不初始化)一个变量,然后在相应的 cpp 实现文件中使用该变量。我想从 Cython 包装器中设置该变量的值。
在下面,您可以找到我的代码的最小版本。
编辑:正如@ead 所指出的,我的原始代码示例不适合重现该问题。这是一个更适合指出问题的最小工作示例。
测试.h
extern int testVariable;
void function1();
void function2();
测试.cpp
#include "test.h"
#include <iostream>
int testVariable;
void function1() {
std::cout << "function1 called, testVariable = " << testVariable << "\n";
}
void function2() {
std::cout << "function2 called, testVariable = " << testVariable << "\n";
}
包装器1.pyx
cdef extern from "test.h":
int testVariable
void function1()
testVariable = 42
cpdef wrapper_function1():
function1()
包装器2.pyx
cdef extern from "test.h":
void function2()
cpdef wrapper_function2():
function2()
主文件
from wrapper1 import wrapper_function1
from wrapper2 import wrapper_function2
if __name__ == '__main__':
wrapper_function1()
wrapper_function2()
安装程序.py
from Cython.Build import cythonize
from setuptools import setup, Extension
sources = [
'*.pyx',
'test.cpp'
]
extensions = [
Extension(name='*', sources=sources, language='c++')
]
setup(name='test',
packages=['test'],
install_requires=["Cython>=0.29.0"],
python_requires='>=3.7',
ext_modules=cythonize(extensions, language_level='3'))
代码是通过命令编译的python3.7 setup.py build_ext --inplace
。
执行时main.py
,输出如下:
function1 called, testVariable = 42
function2 called, testVariable = 0
调用时,function1
一切都按预期工作,即testVariable
设置为 42。调用function2
时,包装在单独的 Cython 文件中,testVariable
似乎未初始化,这让我感到惊讶,因为testVariable
它应该是一个全局变量。
我将包装器拆分为两个 pyx 文件,因为我实际上不想function2
从 Python 调用,而是从 C++ 调用(为简洁起见,此处未显示代码)。从 C++ 调用函数时,问题依然存在,即为testVariable
0。
感谢您的回答!
PS:我的代码灵感来自https://stackoverflow.com/a/52925796
解决方案
我会使用一个类来解决这个问题,比如:
标题
extern int m_nfoo;
class __declspec(dllexport) MyCppClass
{
public:
MyCppClass();
~MyCppClass(void);
int GetFoo();
void SetFoo(int Foo);
....
C++:
int m_nFoo=0;
int MyCppClass::GetFoo()
{
return m_nFoo;
}
void MyCppClass::SetFoo(int Foo)
{
m_nFoo=Foo;
}
像素:
cdef extern from "MyCppClass.h":
cdef cppclass MyCppClass:
MyCppClass()
int GetFoo()
void SetFoo(int Foo)
皮克斯:
cdef class myClass:
"""
wrapper of MyCppClass
"""
def __cinit__(self):
self.thisptr = new MyCppClass()
def setFoo(self,foo):
self.thisptr.SetFoo(foo)
def getFoo(self):
return self.thisptr.GetFoo()
在一些py中:
I=myClass()
I.setFoo(42)
print ('foo=',I.getFoo())
这很好用
推荐阅读
- react-native - 升级到 react-native 0.58 后,Jest 测试中断
- python - Python群聊使用UDP套接字的问题
- r - 提供双轴时缺少数据 - 多条迹线到子图
- javascript - 在 HTML/Javascript 中创建页面导航
- python - 是否可以在同一个笔记本中运行 Matlab 和 Python?
- ruby-on-rails - 在与另一个控制器相关的视图中构建与控制器相关的表单?
- python - Azure 标记更新“NoneType”对象没有属性“更新”
- rotation - 处理:立方体旋转移动时停留在一个地方
- asp.net - 停止调试后能否保持 ASP.NET Core 网站运行?
- archer - RSA Archer - 如何在 iView 中显示视频或执行 .exe 文件