我试图使用cython包装用c++编写的动态链接库。最后,我将无法访问源代码,因此c++源代码本身不能用于编译包装器、jus .dll
、.lib
和.h
。一切都很好。然而,我立即发现字符串的表现并不好。例如,返回一个简单字符串的dll函数不能正常工作: cython代码总是得到一个空字符串。我在windows 7上,我已经验证了以下内容。
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();
用于编译C++的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()
我使用命令进行编译
$ python setup.py build_ext --inplace --force && python -u main.py
运行此打印
b'abcdefg'
42
debug... # printed by the dll function ReturnSomeString()
b'' # Should've printed: b'Hello World!'
我们可以验证是否真的调用了来自MyDLL的MyDLL(),因为它向stdout发送了一些文本。
我有什么没查的?
发布于 2016-07-15 11:33:11
多亏了@hakala所指出的this answer,我发现调试/发布模式很重要。我并没有想到它能做到。我引述如下:
C++标准库有它自己的一组ABI问题。不能保证给定的STL类型在内存中的布局方式相同,也不能保证给定的STL类从一个实现到另一个实现具有相同的大小(特别是,调试构建可以将额外的调试信息放入给定的STL类型)。因此,任何STL容器都必须在通过DLL边界并在另一侧重新打包之前被解压缩为基本类型。
实际上,在发布模式下编译DLL使OP中的示例工作起来。
https://stackoverflow.com/questions/38393393
复制相似问题