从 python ctypes 中的 c++ dll 传递向量

Posted

技术标签:

【中文标题】从 python ctypes 中的 c++ dll 传递向量【英文标题】:passing vector from a c++ dll in python ctypes 【发布时间】:2018-04-10 03:32:23 【问题描述】:

我有一个用 c++ 编写的带有 extern "C" 的 .dll,这个函数称为 BOLHA 并返回一个双精度值。

问题在于 BOLHA 在参数中有一个vector<double>

extern "C" myDLL_API double BOLHA(vector<double> OI);

实际上由于extern "C",我相信这个向量变成了一个指针,所以我尝试如下加载函数。

mydll = cdll.LoadLibrary("_DLL.dll")

func = mydll.BOLHA

func.argtypes = [POINTER(c_double)]
func.restype = c_double

returnarray = (c_double * 2)(0.047948, 0.005994)

func(returnarray)   

但我收到以下错误。

[Error -529697949] Windows Error 0xE06D7363

【问题讨论】:

vector&lt;double&gt; 不是 C 数据类型。 但是当我使用 extern "C" 时,我认为编译器能够在 C 数据类型上处理它 被传递的vector 只能由满足以下条件的客户端成功使用:1) 使用与构建 DLL 相同的 C++ 编译器和版本,2) 客户端必须使用相同的编译器编译其代码作为 DLL 的选项,3) 必须使用 DLL 使用的相同堆。换句话说,您在哪些客户端可以实际使用您的 BOLHA 功能方面受到高度限制。 如果您能够修改 DLL 代码,您可能希望将 vector 的使用封装在一个类中,您可以在其中创建和从外部获取指针。 extern "C" 不会将 std::vector 转换为指针 - 它只是禁用名称处理。您可以尝试 cython 从 python 访问 c++ 代码。 【参考方案1】:

事实上由于 extern "C" 我相信这个向量变成了一个指针

这是错误的。默认情况下,没有任何机制可以实现这一点。 您的BOLHA() 函数需要接收double*,然后将其转换为vector&lt;double&gt;,或者只使用原始指针。

如果您希望它与vector&lt;double&gt; 签名一起使用,您需要一些东西来完成将指针转换为向量的工作。 boost::python 可以做到这一点,但这需要您使用的 DLL 是 python 模块,而不仅仅是任何 DLL。

如果你有这个功能:

extern "C" myDLL_API double BOLHA(vector<double> OI);

您需要声明一个新函数:

extern "C" myDLL_API double BOLHA_raw(double* ptr, int size) 
    vector<double> v(ptr, ptr+size);
    return BOLHA(v);

【讨论】:

您能否举个例子,如何将参数中的原始指针转换为函数内的 Vector 中? 添加了一个使用迭代器构造函数的编辑。 @PatrickMachado 这是非常基本的东西,您可以在任何 C++ 参考资料中查找。

以上是关于从 python ctypes 中的 c++ dll 传递向量的主要内容,如果未能解决你的问题,请参考以下文章

将 C++ 中的“extern C”与 ctypes 的向量一起使用

使用 ctypes 在 python 中使用 C++ 库

为啥 2019 年我们仍然不能使用 ctypes 从 Python 调用 C++?

如何使用 ctypes 将数组从 C++ 函数返回到 Python

AttributeError:python:未定义符号:使用 ctypes 从 Python 访问 C++ 函数时

如何通过 ctypes 将(非空)列表从 Python 传递到 C++?