我一直在尝试将 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.dll
by 中找到一个真正的函数名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] 删除。
我来说两句