结构体传参: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. .netcore2.1 ef 使用外键关联查询

    //实体类 [Table("invoiceinfo", Schema = "obs")] public class invoice { [Key] public ...

  2. Angular(05)- 组件知识点脑图

    点击左键 => 拖拽图片 => 新标签页查看图片 => 放大拖拽查阅

  3. 将Android封装库通过gradle部署到maven私服并依赖使用

    一.在需要发布的模块chrisbaselibrary下的build.gradle中添加以下部分 //maven插件 apply plugin: 'maven' //打包main目录下代码和资源的 ta ...

  4. 字符串 string方法

    字符串 name = 'ab c dd' i = name.find('a', 1, 3) # 找到返回对应下标 找不到返回-1 print(i) j = name.rfind('d') # 寻找对应 ...

  5. 检测值是否存在(??)(Freemarker的null值处理)

    使用形式: unsafe_expr?? 或 (unsafe_expr)?? 这个操作符告诉我们一个值是否存在.基于这种情况, 结果是 true 或 false. 访问非顶层变量的使用规则和默认值操作符 ...

  6. CountDownLatch(倒计时计数器)使用说明 --并发

    方法说明:   public void countDown()      递减锁存器的计数,如果计数到达零,则释放所有等待的线程.如果当前计数大于零,则将计数减少.如果新的计数为零,出于线程调度目的, ...

  7. ETC到底要不要办?有什么好处?

    一说到ETC,开车的朋友想必不会陌生.但很多车友却不太愿意办理ETC, 究其原因,主要是一些谣言所致,一传一十传百最后变成了真实的谎言,并且对此深信不疑, 比如下面5个广泛流传的谣言     在来看看 ...

  8. github仓库迁移到gitlab以及gitlab仓库迁移到另一个gitlab服务器

    一. github仓库迁移到gitlab 先进入 new project: 选择 Import project, 选择下面的github: 进入后,这里需要github的 personal acces ...

  9. go语言之if语句和switch语句和循环语句

    1.if语句 package main import ( "fmt" "io/ioutil" ) func main() { //流程控制 //使用常量定义一个 ...

  10. Linux之自动化部署

    No.1 自动化部署git项目 一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一 ...