您的位置:首页 > 编程语言 > C语言/C++

3.Python调用C语言之使用指针

2014-08-10 15:34 281 查看
之前讲了Python调用C语言的基本方法,但是只能进行最简单的操作。现在我们就来讲讲如何Python如何操作C语言指针。

掌握调用指针的方法,我们首先要了解2个函数byref和POINTER,还是先看看他们的doc吧

1.byref



2.POINTER(这一定是个不合格的程序员写的,没有留doc

)



好吧,byref翻译过来就是:返回一个C语言的指针,只能用作函数的参数,和C语言传入参数时使用&差不多的意思(个人理解哈)。POINTER没写doc,不过个人理解是将事物指针化,和C语言中初始化变量时使用 * 相当,不过不能用作参数。如果这部分有错请留言!!!

 接下来我们看个实例吧。

Example 1:

首先附上DLL代码,代码中参数和返回值均指针化了

#include "stdafx.h"
#include <stdio.h>
#define DLLAPI extern "C" _declspec(dllexport)

typedef struct Testdll
{
int a;
char* b;
}testdll;

DLLAPI testdll* test(testdll* t)
{
t->a=t->a+t->a;
printf("%d\n%s\n",t->a,t->b);
return t;
}

然后附上python代码,就是拿上一次的代码改了改,节约时间,勿喷!!
#coding=gbk
from ctypes import *

dllpath='C:\\Users\\***\\Documents\\Visual Studio 2010\\Projects\\EasyDll\\Release\\EasyDll.dll'
dll=CDLL(dllpath)

a=c_int(125)
b=c_char_p('Hello world,Hello Chengdu')

class testdll(Structure):
_fields_=[('a',c_int),
('b',c_char_p)]

t=testdll()#初始化结构体
t.a=a
t.b=b

dll.test.restype=POINTER(testdll)#确定test这个函数的返回值的类型

t=dll.test(byref(t))#执行函数
print t.contents.a
print t.contents.b
x=raw_input('any key to continue')


好吧,我们看见这个和第二部分的代码基本差不多。不同的地方有3个。
1.dll.test.restype中,test的返回值类型使用了POINTER函数,也就是说,如果一个链接库中函数返回值有指针,那么在Python中赋予函数返回值的时候就需要使用POINTER将结构体指针话

2.调用链接库的test函数时,使用了byref函数。意思若链接库里面的函数参数为指针,那么python中参数参数需要用byref取结构体地址

3.在获取结构体值的时候,指针类型结构体里面的值是在contents里面。如果python接受到一个指针类型的结构体,那么他们的值全部都在contents里面

但是,呵呵,一运行的时候你会发现一个非常非常奇怪的现象。



为毛会这样,接收到的值全部为空????????????

我将代码进行一下小小的改动



然后运行



结果完全正确,我陷入了沉思~~~

为什么会这样?为了探究这个问题,我们再一次修改代码,添加一行如图画红圈所示。



执行


  

我可以看到,在第一个t=dll.test(byref(t))中,执行完了之后t其实就已经被释放掉了。至于原因,不再这里长篇大论了,后面再详谈~~~,大家暂时先注意一下这个问题就行了~
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: