C++ DLL 返回从 Python 调用的指针

Posted

技术标签:

【中文标题】C++ DLL 返回从 Python 调用的指针【英文标题】:C++ DLL returning a pointer called from Python 【发布时间】:2016-07-21 20:36:31 【问题描述】:

我正在尝试从 python 访问 C++ dll(我是 Python 新手)。我克服了许多调用约定问题,最终让它运行而没有任何编译/链接错误。但是,当我在 python 中从 C++ dll 打印返回数组时,它会显示所有随机初始化值。似乎没有正确返回值。

我的 C++ 代码如下所示。

double DLL_EXPORT __cdecl *function1(int arg1, int arg2, double arg3[],int arg4,double arg5,double arg6,double arg7, double arg8)
     
        double *Areas = new double[7];

        ....Calculations

        return Areas;

我的python代码如下:

import ctypes

CalcDll = ctypes.CDLL("CalcRoutines.dll")

arg3_py=(ctypes.c_double*15)(1.926,1.0383,0.00008,0.00102435,0.0101,0.0,0.002,0.0254,102,1,0.001046153,0.001046153,0.001046153,0.001046153,20)
dummy = ctypes.c_double(0.0)

CalcDll.function1.restype = ctypes.c_double*7
Areas = CalcDll.function1(ctypes.c_int(1),ctypes.c_int(6),arg3_py,ctypes.c_int(0),dummy,dummy,dummy,dummy)

for num in HxAreas:
    print("\t", num)

打印语句的输出如下:

     2.4768722583947873e-306
     3.252195577561737e+202
     2.559357001198207e-306
     5e-324
     2.560791130833573e-306
     3e-323
     2.5621383435212475e-306

非常感谢任何关于我做错的建议。

【问题讨论】:

请注意,对于不同的编译器,返回结构的函数并不总是以相同的方式执行此操作(我很难学到这一点)。您的 C++ 编译器返回此类结构的方式可能与您的 Python 版本所期望的方式不兼容。 ***.com/a/6731737/95954 最好返回一个使用malloc() 分配的双精度数组,以便可以通过ctypes 释放它。 还有:***.com/a/6726624/95954 @J.J.Hakala:仅当 ctypes 能够使用相同的内存管理器时。当 C 内存管理器在 DLL 中而 ctypes 不在时,这非常不太可能。请参阅我的第三条评论中的链接:将显式 poibter 传递给调用者分配的缓冲区。 DLL 只复制到缓冲区中。 【参考方案1】:

代替

CalcDll.function1.restype = ctypes.c_double * 7

应该有

CalcDll.function1.restype = ctypes.POINTER(ctypes.c_double)

然后

Areas = CalcDll.function1(ctypes.c_int(1), ctypes.c_int(6), arg3_py,
                          ctypes.c_int(0), dummy, dummy, dummy, dummy)

for i in range(7):
    print("\t", Areas[i])

我不确定 ctypes 在 'ctypes.c_double * 7' 的情况下会做什么,如果它试图从堆栈中提取七个双精度数或什么。

经过测试

double * function1(int arg1, int arg2, double arg3[],
                   int arg4, double arg5, double arg6,
                   double arg7, double arg8)

    double * areas = malloc(sizeof(double) * 7);
    int i;

    for(i=0; i<7; i++) 
        areas[i] = i;
    

    return areas;

使用restype = ctypes.POINTER(ctypes.c_double) 正确打印数组中的值

【讨论】:

以上是关于C++ DLL 返回从 Python 调用的指针的主要内容,如果未能解决你的问题,请参考以下文章

使用 Python 从 c++ dll 返回数据

当参数之一是指针数组时,如何从 C# 调用 C++ DLL

使用指针调用 C++ DLL 函数

C#怎么调用C++的dll?

如何从 MSVC 中的 libsndfile-1.dll 访问函数?

python调用dll怎么传入一个指针接收结果?