bcb dll返回字符_python调用C++ DLL 传参技巧

387e3ac65ade9cdb1b859e8099f1db3a.png

准备工作:

C++文件(cpp):(注意在函数声明上加上extern "C" 的修饰)

#include
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        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个的字符定义为STRcast(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=' '
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值