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

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

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

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

import ctypes
print '\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.msvcrt
str = "hahahahah!"
msvcrt.printf("Hello %s\n", str)
x=raw_input()

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

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

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



        

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值