背景
在使用MP300做功能测试的时候,测量电压的函数涉及到二级指针,在测试时先注释跳过了,现在回来重新研究
先学知识
为什么要使用二级指针
在C++中,函数的参数是对实参进行拷贝,在函数中修改形参将不会对外部的实参产生影响(即函数完成计算后返回计算结果,但对传入的参数数值不作改变)
为了改变传入的参数,则使用了指针,指针指向参数的地址,指针可以通过地址找到参数并修改参数的值(指向【变量】的指针)
而当传入的参数是指针时,为了修改指针的值,可以将指针本身看成一个变量,此时再使用指针就可以修改其值,这就是二级指针(指向【指针】的指针)
形参和是实参的区别
形参是用于参与函数内计算的变量
实参是调用该函数时给变量的大小
假设变量为i=5,其地址是0x000001
设指针p,指针所处的地址是0x000020(&p = 0x000020),指针p指向i的地址,即对p进行解引用能够得到i的值(*p = i = 5)
设二级指针pp,pp所处的地址是0x000030(&pp = 0x000030),指针pp指向p的地址,即对pp进行一级解引用能够得到p的值(p的值保存的是i的地址)(pp = p =&i = 0x000001),对pp进行二级解引用能够得到i的值(相当于对上级解引用出来的p再进行一次解引用)(*pp = *p = i = 5)
而通过修改二级指针的一级解引用的值(即p的值),就可以修改指针p指向的地址,即修改一级指针所指向的值
此时,*p = j = 10,*pp = p = &j =0x000004,**pp = *p = j = 10
如何在python中调用dll的函数
【pycharm】python调用DLL_pycharm调用dll_LucXiong的博客-CSDN博客
通常使用内置ctypes模块完成DLL中c变量类型与python变量类型的对应
首先要引入ctypes模块
格式为
from ctypes import *
定义调用函数的数据类型
格式为
ddl名.调用函数名.argtypes = [传入数据类型]
ddl名.调用函数名.restypes = [返回数据类型]
这一步的目的是为了让编译器判断参数是否符合函数所对应的数据类型
注意:在python中引入C++后数据类型有改变
Python&C++相互混合调用编程全面实战-03ctypes类型对应_c_void_p_虚坏叔叔的博客-CSDN博客
解决
以调用MP300中测试电压的函数MPS_GetMeasureVoltage为例,其函数原型是
继续阅读手册给出的例子,可知必须的步骤为开始测量->获得测量电压
当参数原型是指针时,调用参数时,需要传入其地址(使用byref()函数获得其地址)
由于传入的类型是指针,因此需要实例化出一个对象,将指针指向这个对象,避免指针所指对象没有数据的问题,否则会引起OSError: exception: access violation writing 0x00000000的报错
不实例化对象会引起'TypeError' LP_LP_c_long instance instead of _ctypes.PyCPointerType报错
原因是由于传递类型而不是实例。 您应该声明参数类型和返回类型,以便 ctypes 可以仔细检查传递的值是否正确。
可参考:python - PYthon ctypes 'TypeError' LP_LP_c_long 实例而不是 _ctypes.PyCPointerType - 堆栈内存溢出
修改后代码如下
在python中,实例函数类型()
表明是一个指针,POINTER(函数类型())表明是一个二级指针
该测量电压函数声明为