『壹』 請教python調用dll動態庫的傳參問題
第一步,我先從簡單的調用出發,定義了一個簡單的函數,該函數僅僅實現一個整數加法求和: LIBEXPORT_API int mySum(int a,int b){ return a+b;} C# 導入定義: public class RefComm { [DllImport("LibEncrypt.dll", EntryPoint=" mySum ", CharSet=CharSet.Auto,CallingConvention=CallingConvention.StdCall)] public static extern int mySum (int a,int b); } 在C#中調用測試: int iSum = RefComm.mySum(,); 運行查看結果iSum為5,調用正確。第一步試驗完成,說明在C#中能夠調用自定義的動態鏈接庫函數。 第二步,我定義了字元串操作的函數(簡單起見,還是採用前面的函數名),返回結果為字元串: LIBEXPORT_API char *mySum(char *a,char *b){sprintf(b,"%s",a); return a;} C# 導入定義: public class RefComm { [DllImport("LibEncrypt.dll", EntryPoint=" mySum ", CharSet=CharSet.Auto, CallingConvention=CallingConvention.StdCall)] public static extern string mySum (string a, string b); } 在C#中調用測試: string strDest=""; string strTmp= RefComm.mySum("45", strDest); 運行查看結果 strTmp 為"45",但是strDest為空。我修改動態鏈接庫實現,返回結果為串b: LIBEXPORT_API char *mySum(char *a,char *b){sprintf(b,"%s",a) return b;} 修改 C# 導入定義,將串b修改為ref方式: public class RefComm { [DllImport("LibEncrypt.dll", EntryPoint=" mySum ", CharSet=CharSet.Auto,CallingConvention=CallingConvention.StdCall)] public static extern string mySum (string a, ref string b); } 在C#中再調用測試: string strDest=""; string strTmp= RefComm.mySum("45", ref strDest); 運行查看結果 strTmp 和 strDest 均不對,含不可見字元。再修改 C# 導入定義,將CharSet從Auto修改為Ansi: public class RefComm { [DllImport("LibEncrypt.dll", EntryPoint=" mySum ", CharSet=CharSet.Ansi,CallingConvention=CallingConvention.StdCall)] public static extern string mySum (string a, string b); } 在C#中再調用測試: string strDest=""; string strTmp= RefComm. mySum("45", ref strDest); 運行查看結果 strTmp 為"45",但是串 strDest 沒有賦值。第二步實現函數返回串,但是在函數出口參數中沒能進行輸出。再次修改 C# 導入定義,將串b修改為引用(ref): public class RefComm { [DllImport("LibEncrypt.dll", EntryPoint=" mySum ", CharSet=CharSet.Ansi,CallingConvention=CallingConvention.StdCall)] public static extern string mySum (string a, ref string b); } 運行時調用失敗,不能繼續執行。 第三步,修改動態鏈接庫實現,將b修改為雙重指針: LIBEXPORT_API char *mySum(char *a,char **b){sprintf((*b),"%s",a); return *b;} C#導入定義: public class RefComm { [DllImport("LibEncrypt.dll", EntryPoint=" mySum ", CharSet=CharSet.Ansi,CallingConvention=CallingConvention.StdCall)] public static extern string mySum (string a, ref string b); } 在C#中調用測試: string strDest=""; string strTmp= RefComm. mySum("45", ref strDest); 運行查看結果 strTmp 和 strDest 均為"45",調用正確。第三步實現了函數出口參數正確輸出結果。 第四步,修改動態鏈接庫實現,實現整數參數的輸出: LIBEXPORT_API int mySum(int a,int b,int *c){ *c=a+b; return *c;} C#導入的定義: public class RefComm { [DllImport("LibEncrypt.dll", EntryPoint=" mySum ", CharSet=CharSet.Ansi,CallingConvention=CallingConvention.StdCall)] public static extern int mySum (int a, int b,ref int c); } 在C#中調用測試: int c=0; int iSum= RefComm. mySum(,, ref c); 運行查看結果iSum 和c均為5,調用正確。 經過以上幾個步驟的試驗,基本掌握了如何定義動態庫函數以及如何在 C# 定義導入,有此基礎,很快我實現了變長加密函數在 C# 中的調用,至此目標實現。 三、結論 在 C# 中調用 C++ 編寫的動態鏈接庫函數,如果需要出口參數輸出,則需要使用指針,對於字元串,則需要使用雙重指針,對於 C# 的導入定義,則需要使用引用(ref)定義。 對於函數返回值,C# 導入定義和 C++ 動態庫函數聲明定義需要保持一致,否則會出現函數調用失敗。定義導入時,一定注意 CharSet 和 CallingConvention 參數,否則導致調用失敗或結果異常。運行時,動態鏈接庫放在 C# 程序的目錄下即可,我這里是一個 C# 的動態鏈接庫,兩個動態鏈接庫就在同一個目錄下運行。
『貳』 怎樣用python調用vc++編出來的win32 DLL
1、首選運行工具 makepy.py。
2、這樣就可以查看 C# dll的 com導出的 py文件了。 Python編程makepy.py代碼如下:
# -*- coding: mbcs -*-
# Created by makepy.py version 0.5.00
# By python version 2.5.4 (r254:67916, Dec 23 2008, 15:10:54)
也可以使用下面的方式:
然後保證你能找到這個dll, 比如在system32下
from ...
windll.aaa 就可以
『叄』 如何用python調用應用程序的.dll文件
python引用DLL文件的方法具體分析如下:
在python中調用dll文件中的介面比較簡單,如我們有一個test.dll文件,內部定義如下:
extern "C"
{
int __stdcall test( void* p, int len)
{
return len;
}
}
在python中我們可以用以下兩種方式載入
1.
import ctypes
dll = ctypes.windll.LoadLibrary( 'test.dll' )
2.
import ctypes
dll = ctypes.WinDll( 'test.dll' )
其中ctypes.windll為ctypes.WinDll類的一個對象,已經在ctypes模塊中定義好的。在test.dll中有test介面,可直接用dll調用即可
nRst = dll.test( )
print nRst
由於在test這個介面中需要傳遞兩個參數,一個是void類型的指針,它指向一個緩沖區。一個是該緩沖區的長度。因此我們要獲取到python中的字元串的指針和長度
#方法一:
sBuf = 'aaaaaaaaaabbbbbbbbbbbbbb'
pStr = ctypes.c_char_p( )
pStr.value = sBuf
pVoid = ctypes.cast( pStr, ctypes.c_void_p ).value
nRst = dll.test( pVoid, len( pStr.value) )
#方法二:
test = dll.test
test.argtypes = [ctypes.c_char_p, ctypes.c_int]
test.restypes = ctypes.c_int
nRst = test(sBuf, len(sBuf))
如果修改test.dll中介面的定義如下:
extern "C"
{
int __cdecl test( void* p, int len)
{
return len;
}
}
由於介面中定義的是cdecl格式的調用,所以在python中也需要用相應的類型
1.
import ctypes
dll = ctypes.cdll.LoadLibrary( 'test.dll' )
##註:一般在linux下為test.o文件,同樣可以使用如下的方法:
##dll =ctypes.cdll.LoadLibrary('test.o')
2.
import ctypes
dll = ctypes.CDll( 'test.dll' )
『肆』 python3,64位的,怎麼樣調用32位的DLL最方便
工作流程:1.創建一個進程外COM伺服器(EXE)。2.將32位dll的介面函數封裝為COM伺服器的相關介面。3.注冊COM伺服器*.exe/regserver(注銷*.exe/unregserver)。4.64位進程調用32位COM伺服器介面,成功。從而曲線實現了64位進程調用32位dll。具體步驟:我首先創建了一個簡單的dll工程,只輸出一個函數intc=add(inta,intb);生成lib和dll然後創建一個進程外COM(EXE類型),內部鏈接dll,添沖昌加方法Method:Add(long*c){*c=add(1,2);}編譯生成。然後注冊COM,盯檔*.exe/regserver最創建一個64位WIN32工程驗證64位環境下方法調用是否正確,經驗證正確!!!結論:以上方法可以解決64位進程調用32位dll的問題32位進程散則扒調用64位dll應該也可以通過這種方法解決,原因64位windows系統下安裝了32位和64位兩套COM系統
『伍』 有誰知道python怎麼調用c#的dll
1、首選運行工具 makepy.py。
『陸』 Windows下如何在python中調用c語言程序編譯的dll
這個dll可能是用borland公司的編譯器編譯出來的。 或者這個dll可能不是在你本機上編譯的,如果你有這個dll的源碼,可以編譯一下,然後放到腳本同一目錄下,再試試。
『柒』 怎樣用python調用vc++編出來的win32 DLL
python調用vc中的API
准備工作: 安裝pywin32-210.5.win32-py2.5.exe
例1:最簡單的MessageBox函數
import win32api, win32gui
import win32con, winerror,win32event,pywintypes
import sys, os,time
win32api.MessageBox(0,'hello', 'WYM',win32con.MB_OK)
例2:進程監控
#Mutex.py
mutex=None
mutex=win32event.CreateMutex(None,pywintypes.FALSE,"MutexWym")
if(win32api.GetLastError() == winerror.ERROR_ALREADY_EXISTS):
print"Opened existing mutex object", mutex
else:
print "Created new mutex"
time.sleep(10)
win32api.CloseHandle(mutex)
print "close Mutex"
time.sleep(10)
#MonitorProcess.py
import win32api, win32gui
import win32con, winerror,win32event ,pywintypes
import sys, os,time
STANDARD_RIGHTS_REQUIRED = 0x000F0000L
SYNCHRONIZE = 0x00100000L
MUTANT_QUERY_STATE = 0x0001
MUTEX_ALL_ACCESS = STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | MUTANT_QUERY_STATE
try:
while 1:
time.sleep(2)
hMutex=win32event.OpenMutex(MUTEX_ALL_ACCESS,pywintypes.FALSE,"MutexWym")
print win32api.GetLastError()
if hMutex is not None:
print "Mutex open"
win32api.CloseHandle(hMutex)
else:
print "Mutex not open"
break
except pywintypes.error, (errno, object, strerror):
print "Error in", object, ":", strerror
如何使用kernel32的API呢
例3:
import pywintypes
import winerror, win32con
import win32api, win32event, win32file, win32pipe, win32process, win32security
import win32service, win32serviceutil, servicemanager,ntsecuritycon
from ctypes import * #本例包括這個頭文件
hMutex = windll.kernel32.CreateMutexA(None, 0, "szMutex")
#其它API同理,比如像windll.kernel32.InitializeCriticalSection() 等等
a、python中涉及的windows下的類型?
通過pywintypes 可以獲得這個數據類型
b、獲得窗口句柄
通過FindWindow這API來查找相應的窗口的句柄,然後發消息給這個窗口,就可以實現這個功能
ct = win32api.GetConsoleTitle()
hd = win32gui.FindWindow(0,ct)
win32gui.ShowWindow(hd,0)