Chinaunix首页 | 论坛 | 博客
  • 博客访问: 19881461
  • 博文数量: 679
  • 博客积分: 10495
  • 博客等级: 上将
  • 技术积分: 9308
  • 用 户 组: 普通用户
  • 注册时间: 2006-07-18 10:51
文章分类

全部博文(679)

文章存档

2012年(5)

2011年(38)

2010年(86)

2009年(145)

2008年(170)

2007年(165)

2006年(89)

分类: Python/Ruby

2011-04-06 08:24:03

Python ctypes

2011-4-6 磁针石 完成初稿,需要以后添加更多的实例

#承接软件自动化实施与培训等gtalk ouyangchongwu#gmail.com qq 37391319
#python qq group:
深圳自动化测试python群:113938272
#
武冈深圳qq群:66250781

参考资料:

Gray Hat Python Python Programming for Hackers and Reverse Engineers 2009

Python的進步: ctypeshttp://blog.ez2learn.com/2009/03/21/python-evolution-ctypes/

Python:使用ctypes库调用外部DLLhttp://www.cnblogs.com/wuchang/archive/2010/04/04/1704456.html

Python调用windowsDLL详解:http://blog.csdn.net/magictong/archive/2008/10/14/3075478.aspx

python 2.7.1参考手册》

 

Ctypes可以调用动态链接库中的函数,可以创建复杂的c数据类型和底层内存处理工具函数。

动态链接库是主进程在执行时链接的编译二进制文件。Windows下面称为dynamic link libraries (DLL)Linux下面叫做:shared objects (SO).。这些二进制文件,通过导出名展示函数,导出名对应着内存中的实际地址。通常运行时,你需要解析函数地址来调用函数,不过ctypes已经为你做好了这些。

Ctypes3中不同的加载动态链接库的方法:cdll(),windll(), oledll(),区别在于库中函数调用的方法和结果返回值。cdll()适用于标准cdecl调用。windll()适用于stdcall调用,是Win32 API的默认方式。oledll()windll()类似,但是设定返回Windows  HRESULT错误码,一般用于COM函数返回的错误消息。

我们来实践一下C语言中的printf()Windows对应msvcrt.dllC:\WINDOWS\system32\),linux对应/lib/libc.so.6

 

Windows代码:

from ctypes import *

msvcrt = cdll.msvcrt

message_string = "Hello world!\n"

msvcrt.printf("Testing: %s", message_string)

 

执行结果:

     Testing: Hello world!

Linux 代码:

from ctypes import *

libc = CDLL("libc.so.6")

message_string = "Hello world!\n"

libc.printf("Testing: %s", message_string)

构建c语言的数据类型:

ctypes type

C type

Python type

char

1-character string

wchar_t

1-character unicode string

char

int/long

unsigned char

int/long

short

int/long

unsigned short

int/long

int

int/long

unsigned int

int/long

long

int/long

unsigned long

int/long

__int64 or long long

int/long

unsigned __int64 or unsigned long long

int/long

float

float

double

float

long double

float

char * (NUL terminated)

string or None

wchar_t * (NUL terminated)

unicode or None

void *

int/long or None

 

ctypes类型可以初始化一个值:

>>> from ctypes import *

>>> c_int()

c_long(0)

>>> c_char_p("Hello world!")

c_char_p('Hello world!')

>>> c_ushort(-5)

c_ushort(65531)

>>> 

>>> seitz = c_char_p("loves the python")

>>> print seitz

c_char_p('loves the python')

>>> print seitz.value

loves the python

>>> exit()

 

传引用只需要使用byref()函数,比如:

function_main( byref(parameter) ).

            结构体的定义:

In C

struct beer_recipe

{

int amt_barley;

int amt_water;

};

In Python

class beer_recipe(Structure):

_fields_ = [

("amt_barley", c_int),

("amt_water", c_int),

]

联合中所有成员变量共享内存,可以把同一变量指定为不同类型。

In C

union {

long barley_long;

int barley_int;

char barley_char[8];

}barley_amount;

In Python

class barley_amount(Union):

_fields_ = [

("barley_long", c_long),

("barley_int", c_int),

("

        见下面python实例:

from ctypes import *

class barley_amount(Union):

_fields_ = [

("barley_long", c_long),

("barley_int", c_int),

("barley_char", c_char * 8),

]

value = raw_input("Enter the amount of barley to put into the beer vat:")

my_barley = barley_amount(int(value))

print "Barley amount as a long: %ld" % my_barley.barley_long

print "Barley amount as an int: %d" % my_barley.barley_long

print "Barley amount as a char: %s" % my_barley.barley_char

        执行结果:

Enter the amount of barley to put into the beer vat: 66

Barley amount as a long: 66

Barley amount as an int: 66

Barley amount as a char: B

        上面实例中的barley_char演示了如何定义数组

阅读(10449) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~