在Python中公开一个C++全局变量
Expose a C++ global variable in Python
我正在尝试使用Cython访问Python代码中的C++全局变量。
假设我的C++代码中有以下数组:
// Project.cpp
int myArr[2] = { 0, 1 };
因此,在Cython中定义一个指向myArr的指针:
cdef extern int * myArr_ptr
myArr_ptr真的指向C++数组吗?或者只是一个随机值?
好的,问题是:
Project.cpp
有一个全局int *myArr;
,它没有列在Project.h
中,并且您希望在不导入Project.cpp
的情况下从Cython访问它。
在评论中,你说:
我无法包含Project.cpp,因为此文件将尝试包含已包含的其他文件,并将尝试重新定义许多变量。
按照你的描述,这里可能有一个基本错误。你可能知道这些基本的事情,所以请不要因为我提起它们而受到侮辱,但我只想彻底一点:
首先,如果您的头文件没有防止多重包含的保护措施,请修复此问题,然后您就不必担心"我不能包含Project.cpp
,因为此文件将尝试包含已包含的其他文件,并尝试重新定义许多变量。"(如果你没有头文件,而你只是在.cpp文件中做所有的事情,到处都有显式的extern
语句,不要这样做——这在C和C++中是个坏主意,早在你开始Cythoning之前。(
其次,如果您的模块要与Project.cpp
所属的.so/.dll/.dlib接口,则不应该针对该库的源代码进行构建,而应该针对已安装的接口进行构建。另一方面,如果您的模块打算直接包含C++代码,则必须包含Project.cpp
。如果您使用extern
声明来引用您不打算链接的内容,那么您只会得到一个链接器错误——或者,如果您运气不好,所有内容都会构建,但在运行时会失败。
第三,如果它实际上不是全局的,那么就不能从Project.cpp
之外进行访问——由于作用域、生存期或链接的原因,在单独的实现文件中没有其他类型的变量可用。
再说一遍,我想你知道所有这些基本的事情,我只是误解了你的评论。是一个真正的问题案例,你需要用一个设计糟糕的API来包装一些东西,这需要你深入内部,有时这可能很棘手,你可能确实遇到了这样的事情,我只是还没有弄清楚具体是怎么回事。
有三个基本的解决方案。
首先,很明显,如果您能够构建一个合适的原生API,那么在Cython中包装API是微不足道的。同时,这对其他原因也很有用。有时,这会花费太多的时间和精力——例如,如果本地库不是为外部驱动而设计的,并且需要10年的遗留维护,而你必须包装它的唯一原因是当前的Cython项目,你可能不想清理它。或者,如果它是一个快速变化的库,你需要跟上时代的步伐,而没有源代码控制,那么分叉并试图保持同步可能是一场噩梦。等等。但如果在你的情况下没有这样的原因,这是正确的答案。如果你只需要cdef extern from "project.h"
,一切都很容易。
您可以通过在本机级别创建一个"shim API",为需要从内部使用的各种函数和类型创建单独的.h
文件,其中包含适当的外部、函数和类型声明,来实现更简单的版本。然后,您可以只使用cdef extern from "project_extras.h"
。
最后,您总是可以为任何内容编写显式的cdef extern
语句,而无需告诉Cython其中任何语句的来源。Cython将在生成的代码中把它转换为适当的本地外部,如果你把一切都做好了,它就会工作。这里有一些缺点——文档解释了您将要放弃的cdef extern from
的所有优点。简短的版本是,您的Cython声明必须与本机声明完全匹配;否则,您将不会在Cython阶段自动修复或引发一个漂亮的错误,而是从C编译器收到一条无法理解的错误消息,该消息指的是无法读取的Cython生成的C代码,而不是您的实际代码,或者更糟的是,指的是编译但做了错误事情的代码。
对于简单的int *
或int []
值,所有这些都无关紧要,因为这不需要任何解释;一个普通的CCD_ 18应该很好。
- 如何创建一个CMake变量,除非显式重写,否则使用默认值
- 删除一个线程上有数百万个字符串的大型哈希映射会影响另一个线程的性能
- 为什么两个不同的未命名名称空间可以共存于一个cpp文件中
- 运行同一解决方案的另一个项目的项目
- 挂起和取消挂起一个文件DLL
- 用C++中的一个变量定义一个常量
- 函数向量_指针有不同的原型,我可以构建一个吗
- 在c++中用vector填充一个简单的动态数组
- 如何在选项卡视图Qt中设置一个新项目,并保存以前的项目
- 预处理器:插入结构名称中的前一个行号
- 我在c++代码中生成了一个运行时#3异常
- 我想将一个对T类型的非常量左值引用绑定到一个T类型的临时值
- 从链接列表c++中删除一个项目
- 告诉一个 const char 数组,除了编译时 C 样式的字符串外,它不以 '