为了账号安全,请及时绑定邮箱和手机立即绑定

在 Python 中编译和连接 C DLL 适用于 Unix,但不适用于 Windows。

在 Python 中编译和连接 C DLL 适用于 Unix,但不适用于 Windows。

弑天下 2021-10-26 16:32:20
所以,我有以下文件:插件程序long int addone(long int x){     return x+1;}然后通过 GCC 7.2.0 的 Windows 安装将其编译成 DLL(我也尝试使用英特尔 C++ 编译器,在将函数更改为 之后extern "C" long int addone(long int x),但是当我尝试将其加载到 Python 时并没有改变结果):gcc -c addone.cgcc -shared -o addone.dll addone.o然后我尝试加载到 python 3.6.7:import ctypes_addone = ctypes.CDLL("addone.dll")尽管我确实设法获得了 CDLL 对象,但它缺少“addone”函数。我已经尝试使用导入 C DLL的ctypes.WinDLL()和ctypes.windll.LoadLibrary方法,但这些方法都实现了相同的最终结果:我从 ctypes 获得一个对象,该对象不拥有公共方法,也没有任何私有方法(在 Python 对象中,而不是 DLL)似乎与 addone 功能有关。只是为了仔细检查我的编译器是否按照我的预期运行,我反汇编了生成的 DLL,它看起来像一个典型的 DLL。在内部,该函数甚至没有名称错误:0000000530ce1030 <add_one>:530ce1030:   55                      push   %rbp530ce1031:   48 89 e5                mov    %rsp,%rbp530ce1034:   48 89 4d 10             mov    %rcx,0x10(%rbp)530ce1038:   48 8b 45 10             mov    0x10(%rbp),%rax530ce103c:   48 83 c0 01             add    $0x1,%rax530ce1040:   5d                      pop    %rbp530ce1041:   c3                      retq530ce1042:   90                      nop<Everything between these two instructions is just more no-ops>530ce104f:   90                      nop我已经能够在 Unix 系统上完成这项工作,并且在该平台上将 C DLL 与 Python 连接起来没有任何问题。然而,转移到 Windows,我觉得我错过了一些东西。即使在另一台机器上尝试所有这些,我仍然无法访问我编写的函数。我觉得我在这里错过了一些东西。我究竟做错了什么?
查看完整描述

2 回答

?
沧海一幻觉

TA贡献1824条经验 获得超5个赞

尝试导出函数:


#include "addone.h"


EXPORT long int addone(long int x){

    return x+1;

}

并制作头文件addone.h:


#define EXPORT __declspec(dllexport)


EXPORT long int addone(long int x);


查看完整回答
反对 回复 2021-10-26
?
慕森卡

TA贡献1806条经验 获得超8个赞

一番折腾之后,我才明白是怎么回事。

该函数确实已正确编写,正确编译为 DLL,并且正确创建了 ctypes.CDLL 对象。

ctypes.CDLL 对象没有立即“看到”函数名,因此它不在方法列表中。我所做的是忽略该方法不在对象的命名空间中这一事实,我大胆地调用了_addone.addone(x). 这使得对象意识到该函数在 DLL 中,并将其添加到命名空间中。

我怀疑 ctypes 中有一些后端正在进行,调用函数会导致它检查该名称是否实际存在于库中。也许这是为了防止命名空间被编译器放置到 DLL 中的各种其他函数弄乱。


查看完整回答
反对 回复 2021-10-26
  • 2 回答
  • 0 关注
  • 205 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信