结构体传参: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*;
} float floatAdd(float a,float b) {
return a+b;
} void HelloWorld(char * str){
puts(str);
} void Ints(int * arr,int n){
for(int i=;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=' ')

python调用C++ DLL 传参技巧的更多相关文章

  1. 『Python × C++』函数传参机制学习以及对比

    一.Python函数传参 在python中,函数传参实际上传入的是变量的别名,由于python内在的变量机制(名称和变量值相互独立),只要传入的变量不可变(tuple中的元素也要是不可变的才行),那么 ...

  2. python 线程创建和传参(28)

    在以前的文章中虽然我们没有介绍过线程这个概念,但是实际上前面所有代码都是线程,只不过是单线程,代码由上而下依次执行或者进入main函数执行,这样的单线程也称为主线程. 有了单线程的话,什么又是多线程? ...

  3. # Python第十节 传参

    Python第十节 传参 一. 变量和变量名 首先说明变量名和变量的一点差异 例如: var = [1, 2, 3] `var = "Google" 调用变量var的时候, 既可以 ...

  4. python字符串格式化--dict传参

    # -*- coding: utf-8 -*- #python 27 #xiaodeng #python字符串格式化--dict传参 print "I'm %(name)s. I'm %(a ...

  5. 简单实现python调用c#dll动态链接库

    在python调用c#dll库时要先安装库clr,即安装pythonnet,参考文章:https://www.cnblogs.com/kevin-Y/p/10235125.html(为在python中 ...

  6. [源码]Python调用C# DLL例子(Python与.Net交互)

    K8Cscan C# DLL例子代码 namespace CscanDLL { public class scan { public static string run(string ip) { if ...

  7. python 传值引用和传参引用

    调用同事的函数,传入goods_list,获取商品信息,然后将商品信息与goods_list的信息进行匹配,合并. 但是同事返回数据的同时改变了我传入的参数,goods_list.相当于传参引用,也就 ...

  8. python函数的动态传参.作用域与命名空间

    一.动态传参1.*表示动态传参. 可以接受所有的位置参数传参的时候自动的把实参打包成元组 交给形参 def chi(*food): print(food) chi() # 动态传参可以不传参数 chi ...

  9. python记录_day10 动态传参 命名空间 作用域

    一.动态传参 动态传参用到 *args 和 **kwargs ,*号表示接收位置参数,args是参数名:**表示接收关键字参数,kwargs是参数名 def chi(*food): print(foo ...

随机推荐

  1. iOS---------金额转大写

    -(NSString *)digitUppercase:(NSString *)numstr{ double numberals=[numstr doubleValue]; NSArray *numb ...

  2. JAVA工程师技能要求

    近期做了个JAVA工程师分类, JAVA工程师可能是市场上最多类的程序员:   初级JAVA工程师的基本要求 Good basic programming skills 良好基本编程技能 Founda ...

  3. MySQL删除大表时潜在的问题(drop table,truncate table)

    来源于:https://www.cnblogs.com/CtripDBA/p/11465315.html,侵删,纯截图,避免吸引流量之嫌 case1,删除大表时,因为清理自适应hash索引占用的内容导 ...

  4. js设置定时执行

    具体语法参考:https://www.runoob.com/jsref/met-win-setinterval.html var timer = window.setInterval(function ...

  5. Could not open requirements file: [Errno 2] No such file or directory: 'requirements.txt

    最近安装python,已经安装好,cmd终端中输入python.pip等命令都有用 然而在配置requirements.txt文件过程中,执行语句 “pip install -r requiremen ...

  6. com.mysql.cj.exceptions.DataReadException: Zero date value prohibited

    com.mysql.cj.exceptions.DataReadException: Zero date value prohibited at com.mysql.cj.result.SqlTime ...

  7. 为什么有的插件安装需要用Vue.use()方法

    问题 相信很多人在用Vue使用别人的组件时,会用到 Vue.use() .例如:Vue.use(VueRouter).Vue.use(MintUI).但是用 axios时,就不需要用 Vue.use( ...

  8. BZOJ3894/LG4313 文理分科 新建点最小割

    问题描述 BZOJ3894 LG4313 题解 显然一个人只能选文/理 -> 一个人只能属于文(S).理(T)集合中的一个 可以把选择文得到 \(art\) 的收益看做选择文失去 \(scien ...

  9. CountDownLatch原理分析

    CountDownLatch原理分析 CountDownLatch是一个同步工具类,它允许一个或多个线程一直等待,直到其他线程执行完后再执行.例如,应用程序的主线程希望在负责启动框架服务的线程已经启动 ...

  10. React 从入门到进阶之路(一)

    在开始 React 学习之前我们先进入官网 https://react.docschina.org/ 看看官方对 React 的解释:React 是用于构建用户界面的JavaScript 库.我们只需 ...