由于指针大小的差异有关,不可能在64位进程中加载32位共享库(例如,.dll,.so,.dylib文件),反之亦然。故经常会碰到一个问题,Python解释器是64位的,但是dll库是32位的,无法通过CDLL方法直接调用32位dll库中的函数。 本文展示了一种使用msl-loadlib来实现64位Python解释器来调用32位动态链接库的方法。 此包包含一个承载 32 位库的 Server32 类和一个 Client64 类,该类向服务器发送请求以作为进程间通信的一种形式与 32 位库进行通信。 mydll.dll文件是一个32位C++库,不能从64位Python解释器中运行的模块加载。该库由在32位进程中运行的MyServer类加载。MyServer在指定的主机地址和端口号上托管库。作为Server32子类的任何类都必须在其构造函数中提供两个参数:主机和端口。在构造函数中包含关键字参数是可选的。 ############################################################################# server端代码
#msl_server.py
from msl.loadlib import Server32 import traceback class MyServer(Server32): def __init__(self, host, port, quiet, **kwargs): try: super(MyServer, self).__init__(path ='mydll', libtype = 'cdll', host = host, port = port, quiet = quiet) self.lib.Init() except Exception: traceback.print_exc() # 可以自定义函数,供client调用 def add(self, a, b): return a+b
# 可以将dll中的函数依次列举出来供调用 def add2(self, a, b): return self.lib.add(a, b) # 当dll中函数特别多时,可以采用以下方法,当调用self.lib.name时,会自动去dll中寻找name函数,并匹配后面的变量 def __getattr__(self, name, *args, **kwargs): return getattr(self.lib, name, *args, **kwargs)
#############################################################################
#############################################################################
client端代码 from msl.loadlib import Client64 class Chr_client(Client64): def __init__(self): try: super(Chr_client, self).__init__(module32='msl_server') except Exception: traceback.print_exc() def __getattr__(self, name, *args, **kwargs): def send(*args, **kwargs): return self.request32(name, *args, **kwargs) return send
#############################################################################
使用方法
c = Chr_client()
c.add(3,5) #调用msl_server.py中封装好的函数
c.funtion(arg1,arg2,arg3) #通过funtion名称调用mydll.dll中的原始函数
描述不清楚之处,可以查看官方文档Access a 32-bit library in 64-bit Python — MSL-LoadLib 0.9.1.dev0 documentationhttps://msl-loadlib.readthedocs.io/en/latest/interprocess_communication.html