新聞中心
- windows
- clion
- cmake
- python10,64位
.dll文件:使用了動(dòng)態(tài)鏈接, 運(yùn)行時(shí)(windows平臺(tái))需要的文件
.lib: 使用了鏈接,編譯時(shí) 需要的文件
新建c++ lib項(xiàng)目,記得選share而不是static
沒有二級(jí)目錄
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行和倒數(shù)一行
的效果相同
__declspec(dllexport) 這是必須要的,否則其他的cmake項(xiàng)目調(diào)用hello()會(huì)有不報(bào)錯(cuò)的錯(cuò)誤
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
,官網(wǎng)的最新版本(currentTime: 2023/01)好像有問題,在其他網(wǎng)站下就行了
如果沒有使用__declspec(dllexport)
將函數(shù)導(dǎo)出,dll文件中就沒有內(nèi)容
一般情況下把測(cè)試程序目錄放在項(xiàng)目目錄下 同時(shí)改cmake就行了,不需要新建項(xiàng)目,但這里是新建了項(xiàng)目
直接看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) # 可執(zhí)行文件,生成exe
target_link_libraries(test_dll make_dll.lib) # 鏈接#
# 動(dòng)態(tài)鏈接時(shí),dll文件要放到exe的同級(jí)目錄或其他目錄, 靜態(tài)庫不用,編譯時(shí)寫進(jìn)去了
四. python ctypes調(diào)用dll文件使用ctype庫更加方便
_dll_path = r'makd_dll.dll'
lib = ctypes.cdll.LoadLibrary(_dll_path)
lib.hello()
但似乎只能調(diào)用c編寫的dll文件,調(diào)用c++編寫的東西會(huì)出錯(cuò),函數(shù)前要加extern "C"
頭文件要這樣導(dǎo)出函數(shù)
extern "C" __declspec(dllexport) void hello();
//或者
extern "C" {
__declspec(dllexport) void hello();
}
關(guān)于ctypes方式下 的c++接口規(guī)范這規(guī)范是自己試出來的,可能還需要改進(jìn)
有了規(guī)范就不需要用python來測(cè)試接口,直接用c++來調(diào)試就行了
- python獲取到的對(duì)象只是個(gè)void類型指針
dll = ctypes.cdll.LoadLibrary(dll_path)
dll.get_sim.restype = simType //沒有指定*void類型將獲得int類型的值
sim = self.dll.get_sim()
- 用數(shù)組代替vector之類的東西,或者,因?yàn)閏type支持結(jié)構(gòu)體,而vector是結(jié)構(gòu)體類型,可以在python端寫一個(gè)vector結(jié)構(gòu)體,具體沒實(shí)現(xiàn)過
- 接口中用了數(shù)組
void setData(float* points);
這將出現(xiàn)一個(gè)問題,無法得知points的長(zhǎng)度
可以約定points[0]表示數(shù)組的長(zhǎng)度,或者
void setData(float* points, int point_len);
- 除結(jié)構(gòu)體外,數(shù)組是最復(fù)雜的數(shù)據(jù)類型
- 從dll中獲取數(shù)組類型的數(shù)據(jù)
float* getArray(){
float result[4];
result[0] = 10;
return result;
}
這個(gè)函數(shù)在c++中得到的result[0] 為10,但python調(diào)用dll得到的卻是個(gè)像地址的數(shù)字,猜想可能是調(diào)用這個(gè)函數(shù)后內(nèi)存就被釋放掉了
解決方法一:雙重指針,簡(jiǎn)單試了試,好像沒用
解決方法二:用指定了長(zhǎng)度的數(shù)組
void getArray(float* result){ //result是個(gè)數(shù)組,長(zhǎng)度要在python調(diào)用前指定
result[0] = 10;
}
python調(diào)用
arr_type = ctypes.float * 10
arr_value = arr_type()
dll.getArray(arr_value)
pint([arr_value[i] for i in range(10)])
由于獲取數(shù)組前先要獲取到數(shù)組長(zhǎng)度,再加一個(gè)函數(shù)
int getArrayLen();
其他方法沒試過
你是否還在尋找穩(wěn)定的海外服務(wù)器提供商?創(chuàng)新互聯(lián)www.cdcxhl.cn海外機(jī)房具備T級(jí)流量清洗系統(tǒng)配攻擊溯源,準(zhǔn)確流量調(diào)度確保服務(wù)器高可用性,企業(yè)級(jí)服務(wù)器適合批量采購(gòu),新人活動(dòng)首月15元起,快前往官網(wǎng)查看詳情吧
文章名稱:python調(diào)用c++dll庫-創(chuàng)新互聯(lián)
瀏覽路徑:http://www.ef60e0e.cn/article/gcjcg.html