python調用列印動態鏈接(python調用動態鏈接的方法)

本文目錄一覽:

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%d\n”,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:\book\code目錄中的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版本及以上。

原創文章,作者:IQGD3,如若轉載,請註明出處:https://www.506064.com/zh-tw/n/129221.html

(0)
打賞 微信掃一掃 微信掃一掃 支付寶掃一掃 支付寶掃一掃
IQGD3的頭像IQGD3
上一篇 2024-10-03 23:26
下一篇 2024-10-03 23:26

相關推薦

  • Python計算陽曆日期對應周幾

    本文介紹如何通過Python計算任意陽曆日期對應周幾。 一、獲取日期 獲取日期可以通過Python內置的模塊datetime實現,示例代碼如下: from datetime imp…

    編程 2025-04-29
  • Python列表中負數的個數

    Python列表是一個有序的集合,可以存儲多個不同類型的元素。而負數是指小於0的整數。在Python列表中,我們想要找到負數的個數,可以通過以下幾個方面進行實現。 一、使用循環遍歷…

    編程 2025-04-29
  • Python周杰倫代碼用法介紹

    本文將從多個方面對Python周杰倫代碼進行詳細的闡述。 一、代碼介紹 from urllib.request import urlopen from bs4 import Bea…

    編程 2025-04-29
  • Python中引入上一級目錄中函數

    Python中經常需要調用其他文件夾中的模塊或函數,其中一個常見的操作是引入上一級目錄中的函數。在此,我們將從多個角度詳細解釋如何在Python中引入上一級目錄的函數。 一、加入環…

    編程 2025-04-29
  • 如何查看Anaconda中Python路徑

    對Anaconda中Python路徑即conda環境的查看進行詳細的闡述。 一、使用命令行查看 1、在Windows系統中,可以使用命令提示符(cmd)或者Anaconda Pro…

    編程 2025-04-29
  • Python字典去重複工具

    使用Python語言編寫字典去重複工具,可幫助用戶快速去重複。 一、字典去重複工具的需求 在使用Python編寫程序時,我們經常需要處理數據文件,其中包含了大量的重複數據。為了方便…

    編程 2025-04-29
  • Python程序需要編譯才能執行

    Python 被廣泛應用於數據分析、人工智慧、科學計算等領域,它的靈活性和簡單易學的性質使得越來越多的人喜歡使用 Python 進行編程。然而,在 Python 中程序執行的方式不…

    編程 2025-04-29
  • 蝴蝶優化演算法Python版

    蝴蝶優化演算法是一種基於仿生學的優化演算法,模仿自然界中的蝴蝶進行搜索。它可以應用於多個領域的優化問題,包括數學優化、工程問題、機器學習等。本文將從多個方面對蝴蝶優化演算法Python版…

    編程 2025-04-29
  • python強行終止程序快捷鍵

    本文將從多個方面對python強行終止程序快捷鍵進行詳細闡述,並提供相應代碼示例。 一、Ctrl+C快捷鍵 Ctrl+C快捷鍵是在終端中經常用來強行終止運行的程序。當你在終端中運行…

    編程 2025-04-29
  • Python清華鏡像下載

    Python清華鏡像是一個高質量的Python開發資源鏡像站,提供了Python及其相關的開發工具、框架和文檔的下載服務。本文將從以下幾個方面對Python清華鏡像下載進行詳細的闡…

    編程 2025-04-29

發表回復

登錄後才能評論