使用 ctypes 访问 DLL 函数

Daigo_diego111

我一直在尝试将 C 代码转换为 DLL 并从 Python 加载它,但我从未成功过。我正在使用 Windows10(64 位)。原始的 C 代码非常简单:

//Filename: my_functions.c
# include <stdio.h>
int square(int i){
    return i*i
}

我总结了迄今为止我尝试过的两种方法。

方法一

首先,我cl.exe在命令提示符下构建了 64 位 dll

call "C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\Common7\Tools\VsDevCmd.bat" -arch=x64
cl.exe /D_USRDL /D_WINDLL my_functions.c /MT /link /DLL /OUT:my_functions.dll /MACHINE:X64

结果,我得到了一个文件my_functions.dll随后,我尝试通过以下 Python 代码(Python 3.8,Spyder)加载它:

# Filename: calling_c_functions.py
from ctypes import *
my_functions = CDLL("./my_functions.dll")
print(type(my_functions))
print(my_functions.square(10))
print("Done")

但是,我得到了错误:

AttributeError: function 'square' not found.

为什么会发生这种情况?根据 Microsoft 中的文档:从 DLL 导出,DLL 文件包含一个导出表,其中包含 DLL 导出到其他可执行文件的每个函数的名称。这些函数需要通过ordinal number访问name(不同于原始名称“square”)。

这让我想到了下面的方法 2。

方法二

基于Python: accessing DLL function using ctypes -- access by function name failed,我首先使用关键字自己创建了一个DLL文件__declspec(dllexport)

//Filename: my_functionsDLL2.dll
#include <stdio.h>
extern "C"
{
    __declspec(dllexport) int square(int i);
}
__declspec(dllexport) int square(int i)
{
   return i * i; 
}

下一步是在my_functionsDLL2.dllby 中找到一个真正的函数名link.exe我在命令提示符下执行了以下操作。

call "C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\bin\link.exe"
link /dump /exports my_functionsDLL2.dll

我应该能够看到函数名称列表,但最终得到以下输出:

Microsoft (R) COFF/PE Dumper Version 14.29.30037.0
Copyright (C) Microsoft Corporation.  All rights reserved.


Dump of file myfunctionsDLL2.dll
myfunctionsDLL2.dll : warning LNK4048: Invalid format file; ignored

  Summary

知道我做错了什么吗?

丹尼尔克莱因斯坦

您在正确的轨道上,但一路上有点困惑 - 获取代码文件并为其添加.dll扩展名不足以将其转换为 DLL,您仍然需要编译它。您的链接器告诉您它不知道如何解析您的文件:

myfunctionsDLL2.dll:警告 LNK4048:格式文件无效;忽略

因为它只知道如何解析真正的可执行文件。


您应该将您的第二个代码文件(您命名的那个my_functionsDLL2.dll重命名my_functions.c- 并按照与第一次相同的方式编译它。但是这一次,因为您添加__declspec(dllexport)到函数定义中,您的编译器 ( cl.exe) 将知道这些函数是要从 DLL 中导出的,并将导出它们,使它们可以通过 ctypes 使用。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

使用ctypes包装DLL函数

使用 ctypes 的 .dll 中的 python 中的 C++ 函数 - 找不到函数和访问冲突

使用Ctypes与Fortran DLL进行接口时发生访问冲突

使用带有Windows dll函数的ctypes键入错误

使用Python调用DLL函数时出现ctypes.ArgumentError

在ctypes中使用dll函数 python 2.7与3.6

如何使用ctypes调用带有双下划线函数名称的DLL函数?

使用Ctypes配置DLL功能

使用Python Ctypes加载dll

诊断使用ctypes在Python中访问的Windows DLL中的内存泄漏

Ctypes问题-不能与64位DLL和32位DLL一起使用-OSError:异常:访问冲突读取

如何使用ctypes将python列表传递给C函数(dll)

在C / C ++ DLL中导出MSVS 2013中的函数以供Mozilla js-ctypes使用

使用Python ctypes运行C dll函数时遇到问题(大小未知的数组输出)

将python列表传递给使用ctypes返回数组数据的“c”DLL函数

Ctypes WindowsError:异常:从另一个dll文件调用DLL函数时写入0x0000000000000000的访问冲突

无法使用ctypes.open()加载dll

Python ctypes使用winmode加载DLL

使用 ctypes 从 DLL 获取常量数组

访问 .exe 导出函数时 Python ctypes 访问冲突

使用 ctypes 访问 16 位指针

如何使用ctypes访问字符指针值?

从Ruby访问C项目上的dll函数

处理对dll函数的多重访问

为什么从dll调用函数并使用record时会出现访问冲突?

使用ctypes windll卸载64位dll时出错

在OS X中使用python的ctypes调用DLL

在 Python 中使用 Ctypes 读取 Dll 的双 c 结构

Azure函数无法访问mscorelib.dll访问被拒绝