1.Python调用C语言之如何调用动态链接库

来源:互联网 发布:怎么买香港阿里云 编辑:程序博客网 时间:2024/06/11 01:22

平时用C&C++和Python比较多,喜欢鼓捣点小玩意儿。之前在《数学之美》这本书里面看见布隆过滤器这个东西,简直是爬虫利器!所以当时用C++写了一个简单的,后来封装成了动态链接库拿来给爬虫用大笑。所以就研究了一下怎么用Ptython调用C语言,写个博文记录一下!

Python调用C语言需要动态链接库的形式,而Python调用动态链接库则需要ctypes这个模块。

首先我们看看ctypes里面有些神马东西,怎么看呢?当然是神奇的dir()函数。

import ctypesprint '\n'.join(dir(ctypes))
大家可以自己把上面代码进去运行查看。

首先要讲的是3个东东,CDLL、windll和oledll。在dir里面,我们会发现一个奇怪的东西,既有Windll又有WINDLL。免得混淆,索性都看看吧。


嗯,就是这样,CDLL、windll和oledll是三个Class。而OleDLL和WinDLL是2个type(PS:类,类型,傻傻分不清楚?Google it)

这3个Class的区别是它们调用的方法和返回值。CDLL加载的库是标准C语言的cdecl。windll加载的库是必须使用stdcall的调用约定。oledll和windll差不多,不过会返回一个HRESULT错误代码,使用COM函数可以获取具体信息.(这一坨来自一本叫做《python灰帽子》的书)

最后,看看实例吧。

首先看看CDLL的,就用那个布隆过滤器啦。

Example1:

首先附上DLL代码,一个很简单的布隆过滤器,来自某博客,被我改了改难过

#include "stdafx.h"#include <iostream>#include <bitset>#include <string>using namespace std;#define DLLAPI extern "C" _declspec(dllexport)const long MAX= 2<<24;bitset<MAX> bloomset;int seeds[7]={3,7,11,13,31,37,61};int getHash(char* str,int n){int result=0;for (int i=0;i<strlen(str);i++){result=seeds[n]*result+(int)str[i];if(result > 2<<24)result%=2<<24;}return result;}DLLAPI void Dir(){cout<<"bool isInBloomSet(char* str)"<<endl;cout<<"bool addBloomSet(char* str)"<<endl;}DLLAPI int isInBloomSet(char* str){for ( int i=0;i<7;i++ ){int hash=getHash(str,i);if(bloomset[hash]==0)return 0;}return 1;}DLLAPI bool addBloomSet(char* str){for(int i=0;i<7;i++){int hash=getHash(str,i);bloomset.set(hash,1);}return true;}

python代码

from  ctypes import *dllpath='C:\\Users\\***\\Documents\\Visual Studio 2010\\Projects\\BloomFiliter\\Release\\BloomFiliter.dll'url=[c_char_p('www.baidu.com'),c_char_p('www.google.com')]bloom=CDLL(dllpath)bloom.Dir()print bloom.addBloomSet(url[0])print bloom.isInBloomSet(url[0])print bloom.isInBloomSet(url[1])print ''x=raw_input()

Exmaple2:

from ctypes import *msvcrt = cdll.msvcrtstr = "hahahahah!"msvcrt.printf("Hello %s\n", str)
x=raw_input()

再看看windll的用法吧,直接调MessageBox牛不牛逼大笑

from ctypes import *;MessageBox = windll.user32.MessageBoxWtest=c_wchar_p("Great")title=c_wchar_p("Hello World")MessageBox(0,test,title, 0)
当然windll可以用LoadLibrary其他符合调用约定的DLL,大家可以试试。

OleDLL具体方法一样,大家有空试试吧。



        

1 0
原创粉丝点击