In my project I am wrapping some C++ code (that I have full control over) with Cython to be able to call the C++ functionality from Python.
In one of the C++ header files I want to use the "extern" keyword to define (but not initialize) a variable, which is then used in the corresponding cpp implementation file. I want to set the value for that variable from within the Cython wrapper.
In the following you can find a minimal version of my code.
Edit: As pointed out by @ead, my original code sample was not suited to reproduce the problem. Here is a minimal working example that is better suited to point out the problem.
test.h
extern int testVariable;
void function1();
void function2();
test.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";
}
wrapper1.pyx
cdef extern from "test.h":
int testVariable
void function1()
testVariable = 42
cpdef wrapper_function1():
function1()
wrapper2.pyx
cdef extern from "test.h":
void function2()
cpdef wrapper_function2():
function2()
main.py
from wrapper1 import wrapper_function1
from wrapper2 import wrapper_function2
if __name__ == '__main__':
wrapper_function1()
wrapper_function2()
setup.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'))
The code is compiled via the command python3.7 setup.py build_ext --inplace
.
When executing the main.py
, the output is as follows:
function1 called, testVariable = 42
function2 called, testVariable = 0
When calling function1
everything works as expected, i.e. testVariable
is set to 42. When calling function2
, which is wrapped in a separate Cython file, testVariable
seems to be uninitialized, which is surprising to me as testVariable
is supposed to be a global variable.
I split the wrapper across two pyx-files, because I do not actually want to call function2
from Python, but from C++ (the code is not shown here for brevity). When calling the function from C++, the problem persists, i.e., testVariable
is 0.
Thanks for your answers!
PS: My code was inspired by https://stackoverflow.com/a/52925796