Python使用ctypes调用c++函数的一些问题

本文分享Python使用Ctypes调用C++的相关问题及解决方法。介绍了生成.so或.dll文件,给出简单示例,阐述传递整型、浮点型、字符串型参数,获取C函数返回值,传递指针、列表与数组,还提及从C++返回数组给Python的简单方法。

Python使用Ctypes调用C++的一些问题

大家好!各位伙伴在接触Python代码时,在某些情况下,需要调用C++的一些函数。自己最近几天在弄这个问题,中间遇到了到了不少的问题,并且网上相关的内容比较少,因此分享这篇文章。本篇文章对很多底层原理没有过多解释,主要是为了去简单地使用,解决一些问题。中间一些内容可能不大准确,但是希望也能帮助大家,如果大家觉得有帮助的话,点个赞哦

本篇文章会分享Python代码如何调用c++,如何传递数值型参数字符串参数指针,以及最实用的Python传递list给c++中的数组

参考资源

自己查阅了很多博客,这方面的资料比较少,然后主要从B站的一个视频中得到了不少灵感,非常感谢那位老师,如果大家有时间可以去学习一下,会有很多收获。主要参考的资源如下:
Ctypes官方文档
B站一位大哥的视频

生成.so文件或.dll文件

在调用C++时,主要使用的是dll文件以及.so文件,很多博客有这方面的介绍,大家可以自行进行查阅。自己主要是使用.so文件来进行调用,在使用时应该差别不大。

一个简单的小示例

首先来看一个简单的示例,大致了解下基本流程,后面会介绍一些更加复杂的情况,比如传递简单的参数,如数字,字符串等,更复杂的还有Python 传递列表 给C++,以及如何从c++ 返回数组 给Python,自己暂时涉猎的深度就这些,如果有大家想要的东西,就接着往下看吧。

咱们来写个简单的HelloWorld程序,.py文件和.cpp文件在一个目录下:

文件目录
C++程序的代码如下所示:

#include<stdio.h>
#include<iostream>
using namespace std;

extern "C"
void test1(){
   
   
    cout << "Hello world" << endl;
}

int main(){
   
   
    return 0;
}

这里要注意如果是c++的话,要想被Python调用的函数要加extern “C”,暂时记住即可,不知道原因暂时不影响。

然后生成.so文件,这里首先要安装一下g++,具体教程很多,大家可以自行搜索去进行解决,然后使用如下命令生成.so文件

g++ -fPIC -shared HelloWorld.cpp -o HelloWorld.so

执行完此命令后,可以发现多了一个.so文件
在这里插入图片描述
现在我们要开始编写我们的Python代码来调用我们写的c++函数了,Python代码如下:

import ctypes
dll = ctypes.cdll.LoadLibrary
lib = dll('./HelloWorld.so')
lib.test1()

前面相当于一个固定的写法,当然也有别的写法,在下才疏学浅,这一种能用就一直用的是这个啦,运行此文件,发现能正确输出:
在这里插入图片描述

传递简单的参数

当然,各位的需求远没有这么简单,有时我们需要传递一些参数,这里介绍一下自己了解的几种参数,包括整数,浮点数,字符串。此过程涉及Python,ctypes,c++之间的数据类型的转化,首先上一张官方文档的图:
在这里插入图片描述

整型参数

int类型可以直接传递,如下所示:

extern "C"
void 
点对问题(closest pair problem)是指在一个平面上给定n个点,找到其中距离最近的两个点的距离。这个问题可以用分治法来解决。具体的实现方法可以参考以下步骤: 1. 将所有点按照x轴坐标排序 2. 分治,将点集分为左右两部分,递归查找左右两部分的最小距离 3. 在中间区域内(横跨左右两部分的区域),找到距离中线最近的两个点的距离 4. 比较以上三个距离,取最小值作为最终结果 下面是一个简单的C++实现代码: ```c++ #include <iostream> #include <algorithm> #include <cmath> using namespace std; struct Point { int x, y; }; bool cmpX(Point a, Point b) { return a.x < b.x; } bool cmpY(Point a, Point b) { return a.y < b.y; } double getDistance(Point a, Point b) { return sqrt(pow(a.x - b.x, 2) + pow(a.y - b.y, 2)); } double merge(Point* points, int left, int mid, int right, double d) { Point* sortedPoints = new Point[right - left + 1]; int index = 0; int i = left, j = mid + 1; while (i <= mid && j <= right) { if (points[i].y < points[j].y) { sortedPoints[index++] = points[i++]; } else { sortedPoints[index++] = points[j++]; } } while (i <= mid) sortedPoints[index++] = points[i++]; while (j <= right) sortedPoints[index++] = points[j++]; for (int i = 0; i < index; i++) { for (int j = i + 1; j < index && sortedPoints[j].y - sortedPoints[i].y < d; j++) { double distance = getDistance(sortedPoints[i], sortedPoints[j]); if (distance < d) { d = distance; } } } return d; } double closestPair(Point* points, int left, int right) { if (left >= right) { return INT_MAX; } int mid = (left + right) / 2; double d1 = closestPair(points, left, mid); double d2 = closestPair(points, mid + 1, right); double d = min(d1, d2); return merge(points, left, mid, right, d); } int main() { int n; cin >> n; Point* points = new Point[n]; for (int i = 0; i < n; i++) { cin >> points[i].x >> points[i].y; } sort(points, points + n, cmpX); double ans = closestPair(points, 0, n - 1); cout << ans << endl; return 0; } ``` 其中,cmpX和cmpY是用于排序的比较函数,getDistance用于计算两点之间的距离,merge用于计算跨越左右两部分的区域内的最小距离,closestPair用于递归查找左右两部分的最小距离并返回最终结果。
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

INEVGVUP

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

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

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

打赏作者

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

抵扣说明:

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

余额充值