‘壹’ 请教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)