在c ++中使用cython cdef公共变量:变量永远不会被初始化

时间:2017-04-21 12:20:12

标签: python c++ cython

我试图将一些简单的cython翻译成c ++:

cdef public int G = 1

然后在我的c ++代码中使用它:

#include <Python.h>
#include "test.h" // The file generated by the cython command
#include <iostream>
int main(int argc, char **argv) {
    std::cout << "G : " << G << std::endl;
}

输出是:

  

G:0

我查看了test.cpp cython生成的文件,在897行,我有

  G = 1;

那么为什么G在main中评估为0?

以下是用于编译的命令:

cython.exe test.pyx -3 --cplus
g++ test.cpp test_main.cpp -IC:\Python36-32\include -LC:\Python36-32\libs -lpython36

1 个答案:

答案 0 :(得分:2)

使用cython时生成的是python扩展模块。您无法将其直接链接到可执行文件中,因为它需要动态导入并链接到libpython。在此过程中,将运行扩展程序的初始化函数,这会导致G设置为1。

所以你应该:

  • 从您的cython中构建一个python扩展(使用-shared并输出DLL)。
  • 在您的主要负载python解释器。在你的程序中,你现在甚至都没有初始化python。
  • 使用PyImport_ImportModule("mymodule")
  • 将其导入主体

未经测试,但你的主要应该是这样的:

#include <Python.h>

int main(int argc, char * argv[])
{
    Py_Initialize();
    PyObject * test_module = PyImport_ImportModule("test");

    // do something with test_module

    Py_Finalize();
    return 0;
}

您可以使用PyObject_GetAttrString()从python获取G,或者因为您将其声明为cdef,您可以使用操作系统的符号解析工具直接访问它,例如GetProcAddress() for Windows。

有可能在加载时动态链接,但仍然使用importmodule让python做初始化魔术,但我不知道如何做到这一点,或者甚至可能。