python調用C++ DLL 傳參技巧


結構體傳參:http://www.jb51.net/article/52513.htm

 

 

准備工作:

C++文件(cpp):(注意在函數聲明上加上extern "C" 的修飾)

#include <stdio.h>
 
extern "C" {
    __declspec(dllexport) int Double(int x);
    __declspec(dllexport) float floatAdd(float a,float b); 
    __declspec(dllexport) void HelloWorld(char * str); 
    __declspec(dllexport) void Ints(int * arr,int n); 
}
 
int Double(int x){
    return x*2;
}

float floatAdd(float a,float b) {
    return a+b;
}

void HelloWorld(char * str){
    puts(str);
}

void Ints(int * arr,int n){
    for(int i=0;i<n;i++){
        printf("%d ",arr[i]);
    }
    puts("");
}

用g++(mingw64位)編譯為dll:

g++ dlltest.cpp -shared -o dlltest.dll -Wl,--out-implib,dlltest.lib
pause

在python腳本中加載dll :

from ctypes import *
dll = cdll.LoadLibrary('DLL/dlltest.dll')

 

1.如果不加任何修飾,默認傳入參數為int,傳出參數也為int

 

2.對於int以外的類型(如float),需要聲明python函數的傳入參數類型傳出參數類型

fun.argtypes=[c_float,c_float]  #定義傳參類型
fun.restype=c_float             #定義返回值類型
a=fun(c_float(1.4),c_float(1.2))
print(type(a))
print(a)

輸出:

<class 'float'>
2.5999999046325684

 

3.對於字符串char* ,在聲明傳入參數類型時,需要聲明為字符指針,然后分配一塊char數組,最后把這個數組強制轉換為字符指針

並且,在把python腳本中的數據結構導入c++中時,需要把str轉換為bytes或者bytesarray類型,並且進行迭代器分解

hello=dll.HelloWorld
hello.argtypes=[POINTER(c_char)]    #傳入參數為字符指針
STR=(c_char * 100)(*bytes("相信你還在這里",'utf-8')) #把一組100個的字符定義為STR
cast(STR, POINTER(c_char))
hello(STR)

輸出:

相信你還在這里

 

4.對於其他數據類型的數組,(例如int*),操作相似:

Ints=dll.Ints
Ints.argtypes=[POINTER(c_int),c_int]
INT=(c_int * 100)(*[1,2,3]) #把列表傳入變長參數args*中
cast(INT, POINTER(c_int))
Ints(INT,c_int(3))

輸出:

1 2 3 

 

5.對於返回值為數組的情況,可以直接使用索引去訪問,但是下標操作[]不是從迭代器中取對象,而是地址偏移:

def fillHoleCpp(im):
    dll = cdll.LoadLibrary("bfs.dll")
    bfs=dll.bfs
    bfs.argtypes = [POINTER(c_int),c_int]
    bfs.restype = POINTER(c_int)
    a = np.asarray(range(16), dtype=np.int32).reshape([4, 4])
    if not a.flags['C_CONTIGUOUS']:
        a = np.ascontiguous(a, dtype=a.dtype)  # 如果不是C連續的內存,必須強制轉換
    IMG = cast(a.ctypes.data, POINTER(c_int))  # 轉換為ctypes,這里轉換后的可以直接利用cty
    cast(IMG, POINTER(c_int))
    length=a.size
    ans=bfs(IMG,c_int(length))
    print(type(ans))
    for i in range(0,length):
        print(ans[i],end=' ')

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM