C++生成.dll文件后在Python中引用(包括传递参数是double型、char*数组,接收参数也为数组)

一、问题描述

博主想要实现的C++函数原型如下:

double* getInfo(int flag, double xyz[], char *xodrPath)

也就是需要传递参数为三个不同类型的参数,返回值为double类型的指针(数组)。

那么如何在Python中如何通过这个函数生成的.dll文件调用getInfo()函数,并将返回参数进行输出呢?

二、动态链接库(.dll)生成

在cmakeList.txt中添加语句:

add_library(libOdr SHARED getOdr.cpp)
target_link_libraries(libOdr ${ODRMANGER_LIB}/libproj.dll.a ${ODRMANGER_LIB}/libODrive.1.5.5.a)

上述语句中,libOdr是指定生成的库文件的名字,注意其生成的时候会自动添加lib关键字所以实际上生成的库文件全名是liblibOdr.dll,如图所示:

在这里插入图片描述
SHARED 表示生成动态链接库也就是后缀名为.dll的库文件;若需要生成静态链接库关键字改为STATIC即可。

getOdr.cpp这是需要生成库文件的.cpp文件,比如博主需要封装的getInfo()方法就是在.cpp文件中。

这条语句中,后边两个非必须项,是博主运行代码需要的链接库,如果.cpp中代码运行不需要链接库则无需添加,只需要target_link_libraries(libOdr) 即可。

上述文件编辑好后,clion可以直接ctrl+F9进行编译,即可在bin目录下看到生成的库文件;也可以

手动点击build进行编译生成库文件。

后续每次更新.cpp文件后都可以直接点Bulid下拉列表中Rebuild就可以重新生成.dll文件。

三、Python中引用

3.1 首先需要导入头文件:

from ctypes import *

3.2 库和函数调用

from ctypes import *

def getOdr(flag, pos, xodrPath):
    # 调用该连接库
    dll = CDLL('F:/libOdr.dll')
    
    # 设定调用函数的返回数据类型,博主是长度为6的double指针数据类型,
    dll.getInfo.restype = POINTER(c_double * 6)
    
    # 将函数参数float数组pos(Python中为float)预处理为C++中的double类型数组
    xyz3 = c_double * 3
    xyz = xyz3()
    for i in range(3):
        xyz[i] = pos[i]

    # 将函数参数预处理为C++中的char*类型(string),这里直接将长度设置为了100可灵活更改
    xodr = (c_char * 100)(*bytes(xodrPath, "utf-8"))
    cast(xodr, POINTER(c_char))
    
    # 调用目标函数getInfo()
    posInfo = dll.getInfo(flag, xyz, xodr)
    result = []
    for i in range(6):
        # 将函数返回结果存储到result数组中
        result.append(posInfo.contents[i])
    return result

说明:

  • CDLL()这个方法是调用链接库的方法(必要的),调用的时候在括号里添加库文件的路径即可,比如博主的.dll文件是在F盘。
  • 代码中的数字可根据实际情况灵活更改
  • C++中的string类型必须通过char*类型通过如上代码进行处理

上述代码中头文件是引用的from ctypes import *,也可以直接 import ctypes ,此时相关代码则需要加上ctypes.,如下:

import ctypes

def getOdr(flag, pos, xodrPath):
    dll = ctypes.CDLL('F:/libOdr.dll')
    dll.getInfo.restype = ctypes.POINTER(ctypes.c_double * 6)
    # char_p_test = bytes("中国", "utf8")  # 汉字需用采用utf8编码
    xyz3 = ctypes.c_double * 3
    xyz = xyz3()
    for i in range(3):
        xyz[i] = pos[i]

    xodr = (ctypes.c_char * 100)(*bytes(xodrPath, "utf-8"))
    ctypes.cast(xodr, ctypes.POINTER(ctypes.c_char))
    posInfo = dll.getInfo(flag, xyz, xodr)
    result = []
    for i in range(6):
        result.append(posInfo.contents[i])
    return result

main函数不变。

四、函数运行

main函数:


if __name__ == '__main__':
    flag = 1
    # pos = [5915.00, -2937.76, 0]
    pos = [40, -1, 20.1659]
    xodrPath = "D:/MCworkspace/odrParser/data/Germany_2018.xodr"
    posInfo = getOdr(flag, pos, xodrPath)
    for i in posInfo:
        print(i)

在这里插入图片描述

图中红框部分数据即为调用函数后返回的6个double类型数据。

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

我宿孤栈

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值