python调用c++dll库-创新互联
- windows
- clion
- cmake
- python10,64位
.dll文件:使用了动态链接, 运行时(windows平台)需要的文件
.lib: 使用了链接,编译时 需要的文件
新建c++ lib项目,记得选share而不是static
没有二级目录
library.h
#ifndef MAKE_DLL_LIBRARY_H
#define MAKE_DLL_LIBRARY_H
#define MAKE_DLL_API __declspec(dllexport)
int MAKE_DLL_API hello();
#endif //MAKE_DLL_LIBRARY_H
tip: 加
#pragma once
跟加1、2行和倒数一行
的效果相同
__declspec(dllexport) 这是必须要的,否则其他的cmake项目调用hello()会有不报错的错误
library.cpp
#include "library.h"
int hello() {
return 0;
}
CMakeLists.txt
cmake_minimum_required(VERSION 3.23)
project(make_dll)
set(CMAKE_CXX_STANDARD 14)
add_library(make_dll SHARED library.h library.cpp)
编译
二. 查看dll 信息由于一般使用64位的python,所以需要选择64位的编译
1. 判断是 32位还是64位使用命令
dumpbin
用记事本打开dll文件
在前几行找字符串 PE
后面接有 L 就是32位,是 d 就是64位
clion ->file ->setting
我用的是visual studio自带的,可以在右边Architechture
切换版本,x86是32位,amd不知什么东西
用软件查看,百度搜DLL Export Viewer
,官网的最新版本(currentTime: 2023/01)好像有问题,在其他网站下就行了
如果没有使用__declspec(dllexport)
将函数导出,dll文件中就没有内容
一般情况下把测试程序目录放在项目目录下 同时改cmake就行了,不需要新建项目,但这里是新建了项目
直接看CMakeLists.txt
cmake_minimum_required(VERSION 3.23)
project(test_dll)
set(CMAKE_CXX_STANDARD 14)
message(${PROJECT_SOURCE_DIR}) # 查看变量
include_directories(${PROJECT_SOURCE_DIR}) # 指定外部头文件路径
link_directories(${PROJECT_SOURCE_DIR}) # 指定lib文件路径
add_executable(test_dll main.cpp) # 可执行文件,生成exe
target_link_libraries(test_dll make_dll.lib) # 链接#
# 动态链接时,dll文件要放到exe的同级目录或其他目录, 静态库不用,编译时写进去了
四. python ctypes调用dll文件使用ctype库更加方便
_dll_path = r'makd_dll.dll'
lib = ctypes.cdll.LoadLibrary(_dll_path)
lib.hello()
但似乎只能调用c编写的dll文件,调用c++编写的东西会出错,函数前要加extern "C"
头文件要这样导出函数
extern "C" __declspec(dllexport) void hello();
//或者
extern "C" {
__declspec(dllexport) void hello();
}
关于ctypes方式下 的c++接口规范这规范是自己试出来的,可能还需要改进
有了规范就不需要用python来测试接口,直接用c++来调试就行了
- python获取到的对象只是个void类型指针
dll = ctypes.cdll.LoadLibrary(dll_path)
dll.get_sim.restype = simType //没有指定*void类型将获得int类型的值
sim = self.dll.get_sim()
- 用数组代替vector之类的东西,或者,因为ctype支持结构体,而vector是结构体类型,可以在python端写一个vector结构体,具体没实现过
- 接口中用了数组
void setData(float* points);
这将出现一个问题,无法得知points的长度
可以约定points[0]表示数组的长度,或者
void setData(float* points, int point_len);
- 除结构体外,数组是最复杂的数据类型
- 从dll中获取数组类型的数据
float* getArray(){
float result[4];
result[0] = 10;
return result;
}
这个函数在c++中得到的result[0] 为10,但python调用dll得到的却是个像地址的数字,猜想可能是调用这个函数后内存就被释放掉了
解决方法一:双重指针,简单试了试,好像没用
解决方法二:用指定了长度的数组
void getArray(float* result){ //result是个数组,长度要在python调用前指定
result[0] = 10;
}
python调用
arr_type = ctypes.float * 10
arr_value = arr_type()
dll.getArray(arr_value)
pint([arr_value[i] for i in range(10)])
由于获取数组前先要获取到数组长度,再加一个函数
int getArrayLen();
其他方法没试过
你是否还在寻找稳定的海外服务器提供商?创新互联www.cdcxhl.cn海外机房具备T级流量清洗系统配攻击溯源,准确流量调度确保服务器高可用性,企业级服务器适合批量采购,新人活动首月15元起,快前往官网查看详情吧
标题名称:python调用c++dll库-创新互联
网站网址:http://hbruida.cn/article/gcjcg.html