I'm trying to wrap a DLL written in c++ using cython. In the end I will not have access to the
source code, so the c++ source itself cannot be used in the process of compiling the wrapper, jus the .dll
, the .lib
and the .h
.
All is compiling well.
However, I immediately found that strings are not behaving well. For instance, dll
functions that return a simple string are not working correctly: the cython code always gets an
empty string. I'm on windows 7. I've verified the following.
- The DLL has been build by Visual Studio 2015 (i.e. v 1900) with the 2015 toolset in debug mode. I tried both compiling with /MTd and /MDd flags. The resulting .lib and .dll file are put in the same folder as all other files below.
My python 3.5 distribution has been built by VS 2015 as well, for 32 bit.
$ python -iu Python 3.5.1 (v3.5.1:37a07cee5969, Dec 6 2015, 01:38:48) [MSC v.1900 32 bit (Intel)] on win32
When I compile with a dummy c++ source that contains such a function that returns a string, it just works. Using the dll it doesn't work.
setup.py:
from distutils.core import setup
from Cython.Build import cythonize
setup(ext_modules=cythonize(
"test.pyx", # our Cython source
))
test.pyx:
# distutils: language = c++
# distutils: libraries = MyDLL
# distutils: include_dirs = .
# distutils: library_dirs = .
from libcpp.string cimport string
cdef extern from "MyDLL.h" namespace "somenamespace":
int ReturnSomeInt()
string ReturnSomeString()
def run():
cdef string s = string(b'abcdefg')
print(s)
cdef int i = ReturnSomeInt()
print(i)
cdef string problem = ReturnSomeString()
print(problem)
MyDLL.h:
__declspec(dllexport) int ReturnSomeInt();
__declspec(dllexport) std::string ReturnSomeString();
Snippet of C++ code that was used to compile MyDLL:
__declspec(dllexport) int ReturnSomeInt() { return 42; }
__declspec(dllexport) std::string ReturnSomeString() { cout << "debug..." << endl; return "Hello world!"; }
main.py:
from test import run
run()
I compile using the command
$ python setup.py build_ext --inplace --force && python -u main.py
Running this prints
b'abcdefg'
42
debug... # printed by the dll function ReturnSomeString()
b'' # Should've printed: b'Hello World!'
We can verify that the ReturnSomeString() from MyDLL is actually called, as it sends some text to stdout.
What didn't I check?