64位python调用32位dll(通过通讯接口socket间接实现)

背景:

众所周知,64位python无法直接引用32位的dll,但在实际工作学习中总会有一些需要调用32位dll的时候,作为胶水语言,若无法使用python对其进行调用,岂不是徒有虚名!为此,总有人另辟蹊径,想到了一个间接的调用方法,首先用32位python对32位dll进行调用,然后再建立64位python和32位python的通讯,通过自定义的判断调节和响应结果,实现在64位python上对该32位dll进行操作。 

 

步骤:

1.  软件安装

32位的python(安装了pythonnet库,用于调用dll)

64位的python

Visual Studio(非必要)

2. 找到一个32位的dll和它的说明文档

 

很多软件都有它的接口文档,为了方便起见,我们用VS2022自己创建一个32位的dll:

ed6dc429b59241a0b9ed5d67dde40401.png

选用x86的编译器,在dll里面声明命名空间为dlltest,里面包含一个名为m_Math的类,类里面有两个简单的函数Sum和Product,分别计算两个数的和以及乘积。

需要记住命名空间、类、函数的名称和用法,这些在一般dll的说明文档都会展现。

代码如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace dlltest
{
    public class m_Math
    {
        public double Sum(double a,double b)
        {
            return a + b;
            
        }
        public double Product(double a, double b)
        {
            return a * b;
        }

    }
}

编译生成一个32位的目标dll

3. 32位python调用32位dll

尝试调用一下dll,执行下里面的函数 :

将生成的dll命名为mdll.dll,和main文件放在同一路径下面,运行下面代码:

6b8105bfdf374d2c971194247cf6ec2b.png

代码如下:

import clr
clr.AddReference("mdll")
import dlltest as Api
m_math=Api.m_Math()
result=m_math.Sum(2,4)
print(result)

输出2+4的结果,调用成功。

4.建立64位python和32位python的通讯

基于socket库,该库为python标准库,无需额外安装

4.1 获取本机IP

      导入socket,执行打印本机IP的语句:

import socket
print(socket.gethostbyname(socket.gethostname()))

运行结果如下,打印出本机IP

08a09ba2688a48ee812096e60d6c33ab.png

4.2 在32位python创建通讯的客户端

自定义接口Port为12345

建立连接,等待服务器的响应,定义响应类型,

如果接受的信息为“sum”,则回复2+4的和,重新等待服务器响应;

如果接受的信息不为“off”,则回复“what”;

如果接受的信息为“off”,则回复“off”,并且跳出循环,终止进程。

代码如下:

import socket
import json
import clr
clr.AddReference("mdll")
import dlltest as Api
m_math=Api.m_Math()

server = socket.socket(socket.AF_INET,socket.SOCK_STREAM)         # 创建 socket 对象
host = socket.gethostbyname(socket.gethostname()) # 获取本地主机名
try:
    if port == None:
        port = 12345
except:
    port = 12345  # 设置端口
server.bind((host, port))        # 绑定端口
server.listen(1)                 # 等待客户端连接

while True:
    conn,addr = server.accept()     # 建立客户端连接
    # print('Connect to Address:', addr)
    data = json.loads(conn.recv(2048).decode())
    print('recive Message:', data)

    if data=="sum":
        msg=str(m_math.Sum(2,4))
        print(msg)
        conn.send(msg.encode('utf-8'))
        conn.close()
        continue
    if data !="off":
        conn.send("what".encode('utf-8'))
        conn.close()
    if data=="off":
        conn.send("off".encode('utf-8'))
        conn.close()
        break



点击运行,会在循环里面等待响应。

 

4.3 64位python中建立通讯和发送指令

定义port = 12345

Message = “sum”   (可根据需求修改)

创建客户端接口,发送并且接受信息,代码如下:

import socket               
import json

port = 12345
Message = "sum"

client = socket.socket(socket.AF_INET,socket.SOCK_STREAM)         

host = socket.gethostname()

client.connect((host, port))

msg = json.dumps(Message)
client.send(msg.encode('utf-8'))

Result=client.recv(1024).decode()
print(Result)



运行一遍看看32位python的输出窗口:

可以看到打印了一次Sum()的结果,并继续等待下一次指令

572f3948461e49159a1fdc845fe0be73.png

再看看64位python的输出窗口:

打印出一个结果 

393766fd080f46af9a50c350bdb15e0f.png

 

当我们发送“off”指令,程序终止,达到释放内存的结果,下一次运行需重新执行上文4.2的步骤

运行结果如下:

2e3ef02346094fa8bbadc690e02b822b.png

 

 5. 总结

利用socket达到64位python调用32位dll的效果,虽然比较繁琐,但也能有效解决一些问题。比如可以使用此方法调用32位的INCA接口,详情参考博主之前的文章。利用PYTHON调用INCA(在INCA7.0和7.2已实现)_愤怒的小香猪的博客-CSDN博客_inca api

 

 

 

 

 

 

  • 2
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值