Python調用C語言之使用指針


之前講了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其實就已經被釋放掉了。至於原因,不再這里長篇大論了,后面再詳談~~~,大家暫時先注意一下這個問題就行了~


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM