在开发的过程中的有的厂家提供的API,或者其他同事写的功能模块用的是C++语言,而因为我们自己菜或者懒习惯使用python脚本语言开发,这里主要讲解如何使用python调用DLL文件(windows平台)在linux平台中使用的.so文件。
1.创建一个DLL项目
项目会自动生成一个pch.cpp文件,主要的代码就是在这个文件下编写
// 调用其他的函数 // 相机的库 #include "AimPositionAPI.h" #include "AimPositionDef.h" #include <fstream> #pragma comment(lib,"AimPosition2.3.2d.lib") // 使用debug模式下的lib和dll组合
在这个cpp文件下导入厂家或者同事写的c++文件
主要通过这句话让DLL文件能够被外部访问
extern "C" {
__declspec(dllexport) int testDemo();
__declspec(dllexport) void testString(char *name);
}
testString的实现函数如下
#include <fstream>
void testString(char* name)
{
ofstream ofs;
ofs.open(name, ios::app);
ofs << "hello";
ofs.close();
cout << "name" << endl;
cout << name << endl;
}
这个函数的功能是给一个路径然后将hello字符串写入到给定的路径。
2点击生成->生成解决方案
打开你Debug或者Release中查看你的DLL文件。
注意如果这里有你导入的厂家所依赖的DLL文件库的话,你也需要全部拷贝到这里。
在这个DLL文件下创建一个 python文件写入如下脚本代码运行即可完成python调用DLL文件库
from ctypes import CDLL, c_char_p
import numpy as np
opencv_dll = CDLL(r"aimDLL.dll")
filename = c_char_p(b'D:\\cppCode\\testDll\\aimDLL\\x64\Debug\\calib\\tex2t.txt')
# 只记录 相机和机械臂坐标
def fun1():
# 按键Q启动标定和获取机械臂
opencv_dll.testDemo()
pass
def fun2():
opencv_dll.testString(filename)
pass
if __name__ == "__main__":
# fun2()
几点需要注意的地方:
1.python文件目前在DLL文件下,如果在其他的位置的想要正确的引用的话执行一个代码
import os
os.chdir("你DLL文件所在文件路径")
opencv_dll = CDLL(r"你的路径/aimDLL.dll")
2.如何使用python给DLL文件传递字符串
在实际的使用中,python传递int float等情况还是比较简单,但是传递字符串还有指针和结构体的时候就比较麻烦了,这里用ctype库中的c_char_p来传递,意思就是c语言的char指针。
3.导入的c++语言缺少.lib或者dll依赖
这个是vs工程中需要给你依赖的DLL和LIB文件一个依赖项
######################## 调用结构体 #################################
C++ 部分 定义一个数组
// 定义结构体返回值给外部使用
struct Aim_pose
{
double Rt[12];
};
对外结构函数testDemo添加一个结构体指针
extern "C" {
__declspec(dllexport) void testDemo(Aim_pose *pose);
// __declspec(dllexport) void testString(char *name);
}
testDemo函数内部给结构体指针赋值
pose->Rt[0] = prlt->Rto[0][0];
编译DLL即可
python调用部分,需要借助ctype
from ctypes import CDLL, Structure, c_char_p, c_double, pointer
import numpy as np
opencv_dll = CDLL(r"D:\cppCode\testDll\aimDLL\x64\Debug\aimDLL.dll")
# import os
# os.chdir("xxxxxx") #如果报错需要这里添加Dll文件的路径
# 创建c语言的结构体
class StructPointer(Structure):
_fields_ = [("pose", c_double * 12)]
# 实例化结构体
aimpose = StructPointer((-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1))
# 只记录 相机和机械臂坐标
def fun1():
# 按键Q启动标定和获取机械臂
opencv_dll.testDemo(pointer(aimpose))
aim_pose = []
for i in range(12):
aim_pose.append(aimpose.pose[i])
print(aim_pose)
if __name__ == "__main__":
fun1()