首页 > 编程知识 正文

python调用打印动态链接(python调用动态链接的方法)

时间:2023-12-18 17:21:47 阅读:317194 作者:RHIT

本文目录一览:

python怎么调用c的动态链接库

Python调用C/C++动态链接库的需求

在自动化测试过程中,难免会遇到语言混合使用的情况,这不,我们也遇到了。初步决定采用Robot Framework作为自动化测试框架后,其支持Java和Python,而Python作为主流的语言,怎么能放弃使用它的机会^_^。 然而产品采用是古老90年代开发的C/S结构,因为古老,当时也没有考虑到对产品的测试进行自动化,Client端并没有预留CLI(Command Line interface)形式的接口,真是雪上加霜啊。

那怎么自动化?采用AutoIT来对客户端界面进行自动化测试?可惜AutoIT对当初开发采用的控件识别不是很好,如果采用控件所在位置来进行控制的方式,又会导致自动化测试并不是很稳定。那么!!!只有自己开发接口了,目前在Client端开发出CLI形式的接口,将其封装为DLL,然后在Robot FrameWork框架中采用Python对DLL进行调用。任务艰巨哪!

Python调用DLL例子

示例一

首先,在创建一个DLL工程(本人是在VS 2005中创建),头文件:

[cpp] view plain copy 在CODE上查看代码片派生到我的代码片//hello.h

#ifdef EXPORT_HELLO_DLL

#define HELLO_API __declspec(dllexport)

#else

#define HELLO_API __declspec(dllimport)

#endif

extern "C"

{

HELLO_API int IntAdd(int , int);

}

CPP文件:

[cpp] view plain copy 在CODE上查看代码片派生到我的代码片//hello.cpp

#define EXPORT_HELLO_DLL

#include "hello.h"

HELLO_API int IntAdd(int a, int b)

{

return a + b;

}

这里有两个注意点:

(1)弄清楚编译的时候函数的调用约定采用的__cdecl还是__stdcall,因为根据DLL中函数调用约定方式,Python将使用相应的函数加载DLL。

(2)如果采用C++的工程,那么导出的接口需要extern "C",这样python中才能识别导出的函数。

我的工程中采用__cdecl函数调用约定方式进行编译链接产生hello.dll,然后Python中采用ctypes库对hello.dll进行加载和函数调用:

[python] view plain copy 在CODE上查看代码片派生到我的代码片from ctypes import *

dll = cdll.LoadLibrary('hello.dll');

ret = dll.IntAdd(2, 4);

print ret;

OK,一个小例子已经完成了,如果你感兴趣,但还没试过,那就尝试一下吧。

示例二

示例一只是一个"hello world"级别的程序,实际运用中更多的需要传递数据结构、字符串等,才能满足我们的需求。那么这个示例将展示,如何传递数据结构参数,以及如何通过数据结构获取返回值。

首先编写DLL工程中的头文件:

[cpp] view plain copy 在CODE上查看代码片派生到我的代码片//hello.h

#ifdef EXPORT_HELLO_DLL

#define HELLO_API __declspec(dllexport)

#else

#define HELLO_API __declspec(dllimport)

#endif

#define ARRAY_NUMBER 20

#define STR_LEN 20

struct StructTest

{

int number;

char* pChar;

char str[STR_LEN];

int iArray[ARRAY_NUMBER];

};

extern "C"

{

//HELLO_API int IntAdd(int , int);

HELLO_API char* GetStructInfo(struct StructTest* pStruct);}

CPP文件如下:

[cpp] view plain copy 在CODE上查看代码片派生到我的代码片//hello.cpp

#include string.h

#define EXPORT_HELLO_DLL

#include "hello.h"

HELLO_API char* GetStructInfo(struct StructTest* pStruct){

for (int i = 0; i ARRAY_NUMBER; i++)

pStruct-iArray[i] = i;

pStruct-pChar = "hello python!";

strcpy (pStruct-str, "hello world!");

pStruct-number = 100;

return "just OK";

}

GetStructInfo这个函数通过传递一个StructTest类型的指针,然后对对象中的属性进行赋值,最后返回"just OK".

编写Python调用代码如下,首先在Python中继承Structure构造一个和C DLL中一致的数据结构StructTest,然后设置函数GetStructInfo的参数类型和返回值类型,最后创建一个StructTest对象,并将其转化为指针作为参数,调用函数GetStrcutInfo,最后通过输出数据结构的值来检查是否调用成功:

[python] view plain copy 在CODE上查看代码片派生到我的代码片from ctypes import *

ARRAY_NUMBER = 20;

STR_LEN = 20;

#define type

INTARRAY20 = c_int * ARRAY_NUMBER;

CHARARRAY20 = c_char * STR_LEN;

#define struct

class StructTest(Structure):

_fields_ = [

("number", c_int),

("pChar", c_char_p),

("str", CHARARRAY20),

("iArray", INTARRAY20)

]

#load dll and get the function object

dll = cdll.LoadLibrary('hello.dll');

GetStructInfo = dll.GetStructInfo;

#set the return type

GetStructInfo.restype = c_char_p;

#set the argtypes

GetStructInfo.argtypes = [POINTER(StructTest)];objectStruct = StructTest();

#invoke api GetStructInfo

retStr = GetStructInfo(byref(objectStruct));#check result

print "number: ", objectStruct.number;

print "pChar: ", objectStruct.pChar;

print "str: ", objectStruct.str;

for i,val in enumerate(objectStruct.iArray):

print 'Array[i]: ', val;

print retStr;

总结

1. 用64位的Python去加载32位的DLL会出错

2. 以上只是些测试程序,在编写Python过程中尽可能的使用"try Except"来处理异常3. 注意在Python与C DLL交互的时候字节对齐问题4. ctypes库的功能还有待继续探索

python 是否有能列出动态链接库中有哪些方法的库

最近看了《Gray hat python》一书,这才知道为什么python是黑客必学的编程语言。通过python的ctypes模块,可以直接调用动态链接库中的导出函数,而且甚至可以直接在python中构建出复杂的C结构体!!!使得python也具备了底层内存操作的能力,再配合python本身强大的表达能力,能不让人激动么。

之前为了在python中调用动态链接库导出的函数,你需要自行解析出这些导出函数的地址。而现在ctypes库会替我们完成这个麻烦的过程,大大方便了我们直接在python中调用C函数的能力。

ctypes模块中有三种不同的动态链接库加载方式:cdll, windll, oledll。不同之处在于链接库中的函数所遵从的函数调用方式(calling convention)以及返回方式有所不同。

cdll用于加载遵循cdecl标准函数调用约定的链接库。windll则用于加载遵循stdcall调用约定的动态链接库。oledll与windll完全相同,只是会默认其载入的函数会统一返回一个Windows HRESULT错误编码。

先复习一下有关函数调用约定的知识:函数调用约定指的是函数参数入栈的顺序、哪些参数入栈、哪些通过寄存器传值、函数返回时栈帧的回收方式(是由调用者负责清理,还是被调用者清理)、函数名称的修饰方法等等。基本上我们最常见的调用约定就是cdecl和stdcall两种。在《程序员的自我修养--链接、装载与库》一书的第10章有对函数调用约定的更详细介绍。

cdecl规定函数参数列表以从右到左的方式入栈,且由函数的调用者负责清除栈帧上的参数。stdcall的参数入栈方式与cdecl一致,但函数返回时是由被调用者自己负责清理栈帧。而且stdcall是Win32 API函数所使用的调用约定。OK,就这么多,够了。

测试一下在Linux平台和Windows平台下通过ctypes模块导入C库中函数的小例子:

Windows 下:

from ctypes import *

msvcrt = cdll.msvcrt

msg = "Hello world!n"

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

Linux下:

from ctypes import *

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

msg = "Hello, world!n"

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

可以看到动态链接库中的printf被直接导入到python中来调用了。

那么,在python中怎么表示C的类型?不用担心,下面这张表就能搞定。

有了这个映射关系,多复杂的C类型也能在python中表达出来。

在C中定义一个联合:

union

{

long barley_long;

int barley_int;

char barley_char[8];

}barley_amount;

而在python中同等的定义为:注意一下python中定义数组的方式。

class barley_amount(Union):

_fields_ = [

("barley_long", c_long),

("barley_int", c_int),

("barley_char", c_char * 8),

]

测试一下这个例子,在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_int

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

如何把python库文件做成动态链接库

你只能用python调用dll库,想那些底层的东西一般都是用c来写的所以下面我给您提供一个调用方式

import ctypes

dll = ctypes.WinDLL('yourDll.dll')

print dll.Sun(1+2)

print dll.count('abacadeafg',ord('a'))

python怎么获取动态网页链接?

四中方法:

'''

得到当前页面所有连接

'''

import requests

import re

from bs4 import BeautifulSoup

from lxml import etree

from selenium import webdriver

url = ''

r = requests.get(url)

r.encoding = 'gb2312'

# 利用 re

matchs = re.findall(r"(?=href=").+?(?=")|(?=href=').+?(?=')" , r.text)

for link in matchs:

print(link)

print()

# 利用 BeautifulSoup4 (DOM树)

soup = BeautifulSoup(r.text,'lxml')

for a in soup.find_all('a'):

link = a['href']

print(link)

print()

# 利用 lxml.etree (XPath)

tree = etree.HTML(r.text)

for link in tree.xpath("//@href"):

print(link)

print()

# 利用selenium(要开浏览器!)

driver = webdriver.Firefox()

driver.get(url)

for link in driver.find_elements_by_tag_name("a"):

print(link.get_attribute("href"))

driver.close()

如何让python调用C和C++代码

二、Python调用C/C++1、Python调用C动态链接库Python调用C库比较简单,不经过任何封装打包成so,再使用python的ctypes调用即可。(1)C语言文件:pycall.c[html]viewplaincopy/***gcc-olibpycall.so-shared-fPICpycall.c*/#include#includeintfoo(inta,intb){printf("youinput%dand%dn",a,b);returna+b;}(2)gcc编译生成动态库libpycall.so:gcc-olibpycall.so-shared-fPICpycall.c。使用g++编译生成C动态库的代码中的函数或者方法时,需要使用extern"C"来进行编译。(3)Python调用动态库的文件:pycall.py[html]viewplaincopyimportctypesll=ctypes.cdll.LoadLibrarylib=ll("./libpycall.so")lib.foo(1,3)print'***finish***'(4)运行结果:2、Python调用C++(类)动态链接库需要extern"C"来辅助,也就是说还是只能调用C函数,不能直接调用方法,但是能解析C++方法。不是用extern"C",构建后的动态链接库没有这些函数的符号表。(1)C++类文件:pycallclass.cpp[html]viewplaincopy#includeusingnamespacestd;classTestLib{public:voiddisplay();voiddisplay(inta);};voidTestLib::display(){cout#include#includeintfac(intn){if(n2)return(1);/*0!==1!==1*/return(n)*fac(n-1);/*n!==n*(n-1)!*/}char*reverse(char*s){registerchart,/*tmp*/*p=s,/*fwd*/*q=(s+(strlen(s)-1));/*bwd*/while(p

怎么调用编写好的python程序

1 使用os.system函数运行其他程序

2 使用ShellExecute函数运行其他程序

3 使用CreateProcess函数运行其他程序

4 使用ctypes调用kernel32.dll中的函数

1 使用os.system函数运行其他程序

os模块中的system()函数可以方便地运行其他程序或者脚本。其函数原型如下所示。

os.system(command) 其参数含义如下所示。

command 要执行的命令,相当于在Windows的cmd窗口中输入的命令。如果要向程序或者脚本传递参数,可以使用空格分隔程序及多个参数。

以下实例实现通过os.system()函数打开系统的记事本程序。

import os # 使用os.system()函数打开记事本程序 os.system('notepad') 0 # 关闭记事本后的返回值 # 向记事本传递参数,打开python.txt文件 os.system('notepad python.txt')

import os # 使用os.system()函数打开记事本程序 os.system('notepad') 0 # 关闭记事本后的返回值 # 向记事本传递参数,打开python.txt文件 os.system('notepad python.txt')

2 使用ShellExecute函数运行其他程序

除了使用os模块中的os.system()函数以外,还可以使用win32api模块中的ShellExecute()函数。其函数如下所示。

ShellExecute(hwnd, op , file , params , dir , bShow )

其参数含义如下所示。

hwnd:父窗口的句柄,如果没有父窗口,则为0。

op:要进行的操作,为“open”、“print”或者为空。

file:要运行的程序,或者打开的脚本。

arams:要向程序传递的参数,如果打开的为文件,则为空。

dir:程序初始化的目录。

Show:是否显示窗口。

以下实例使用ShellExecute函数运行其他程序。

import win32api # 打开记事本程序,在后台运行,即显示记事本程序的窗口 win32api.ShellExecute(0, 'open', 'notepad.exe', '','',0)

# 打开记事本程序,在前台运行 win32api.ShellExecute(0, 'open', 'notepad.exe', '','',1)

# 向记事本传递参数,打开python.txt win32api.ShellExecute(0, 'open', 'notepad.exe', 'python.txt','',1)

# 在默认浏览器中打开网站 win32api.ShellExecute(0, 'open', '', '','',1)

# 在默认的媒体播放器中播放E:song.wma win32api.ShellExecute(0, 'open', 'E:\song.wma', '','',1)

# 运行位于E:bookcode目录中的MessageBox.py脚本 win32api.ShellExecute(0, 'open', 'E:\book\code\MessageBox.py', '','',1)

可以看出,使用ShellExecute函数,就相当于在资源管理器中双击文件图标一样,系统会打开相应的应用程序执行操作。

3 使用CreateProcess函数运行其他程序

为了便于控制通过脚本运行的程序,可以使用win32process模块中的CreateProcess()函数。其函数原型如下所示。

CreateProcess(appName, commandLine , processAttributes , threadAttributes , bInheritHandles , dwCreationFlags , newEnvironment , currentDirectory , startupinfo )

CreateProcess(appName, commandLine , processAttributes , threadAttributes , bInheritHandles , dwCreationFlags , newEnvironment , currentDirectory , startupinfo )

其参数含义如下。

appName:可执行的文件名。

commandLine:命令行参数。

rocessAttributes:进程安全属性,如果为None,则为默认的安全属性。

threadAttributes:线程安全属性,如果为None,则为默认的安全属性。

InheritHandles:继承标志。

dwCreationFlags:创建标志。

ewEnvironment:创建进程的环境变量。

currentDirectory:进程的当前目录。

tartupinfo :创建进程的属性。

以下实例使用win32process.CreateProcess函数运行记事本程序。

import win32process win32process.CreateProcess('c:\windows\notepad.exe', '', None , None , 0 ,win32process. CREATE_NO_WINDOW , None , None , win32process.STARTUPINFO()) (, , 280, 3076) # 函数返回进程句柄、线程句柄、进程ID,以及线程ID

import win32process win32process.CreateProcess('c:\windows\notepad.exe', '', None , None , 0 ,win32process. CREATE_NO_WINDOW , None , None , win32process.STARTUPINFO()) (?XML:NAMESPACE PREFIX = PYHANDLE /, , 280, 3076) # 函数返回进程句柄、线程句柄、进程ID,以及线程ID

有了已创建进程的句柄就可以使用win32process.TerminateProcess函数结束进程,或者使用win32event.WaitForSingleObject等待创建的线程结束。其函数原型分别如下。

TerminateProcess(handle, exitCode) WaitForSingleObject(handle, milliseconds )

对于TerminateProcess参数含义分别如下。

handle:要操作的进程句柄。

exitCode:进程退出代码。

对于WaitForSingleObject参数含义分别如下。

handle:要操作的进程句柄。

milliseconds:等待的时间,如果为?1,则一直等待。

以下实例实现创建进程后并对其进行操作。

import win32process # 打开记事本程序,获得其句柄 handle = win32process.CreateProcess('c:\windows\notepad.exe', '', None , None , 0 ,win32process. CREATE_NO_WINDOW , None , None , win32process.STARTUPINFO()) # 使用TerminateProcess函数终止记事本程序 win32process.TerminateProcess(handle[0],0) # 导入win32event模块 import win32event # 创建进程获得句柄 handle = win32process.CreateProcess('c:\windows\notepad.exe', '', None , None , 0 ,win32process. CREATE_NO_WINDOW , None , None , win32process.STARTUPINFO()) # 等待进程结束 win32event.WaitForSingleObject(handle[0], -1) 0 # 进程结束的返回值

import win32process # 打开记事本程序,获得其句柄

handle = win32process.CreateProcess('c:\windows\notepad.exe', '', None , None , 0 ,win32process. CREATE_NO_WINDOW , None , None , win32process.STARTUPINFO()) # 使用TerminateProcess函数终止记事本程序

win32process.TerminateProcess(handle[0],0) # 导入win32event模块

import win32event # 创建进程获得句柄

handle = win32process.CreateProcess('c:\windows\notepad.exe', '', None , None , 0 ,win32process. CREATE_NO_WINDOW , None , None , win32process.STARTUPINFO()) # 等待进程结束

win32event.WaitForSingleObject(handle[0], -1) 0 # 进程结束的返回值

4 使用ctypes调用kernel32.dll中的函数

使用ctypes模块可以使Python调用位于动态链接库中的函数。在Python 2.5版中已经包含了ctypes模块。如果使用其他版本的Python,可以到网站下载安装。ctypes适用于Python 2.3版本及以上。

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。