所有,我发现了一些关于如何在python中调用c文件的信息,在这些例子中:有一个ac文件,其中包含许多其他头文件,这个c文件的最开头是#include Python.h
,然后我发现#include Python.h
实际上涉及许多其他头文件,例如pystate.h
,object.h
等,所以我包含了所有必需的头文件。在cpp IDE环境中,它没有显示错误。 我想要做的是在python中调用此c代码,所以from ctypes import *
,然后似乎应该通过以下代码生成dll
:{{1} },但在这种情况下如何使用cl -LD test.c -test.dll
?我使用了cygwin:cl
,它运行正常。任何人都可以帮我这个,即:在python中调用C ?我能说清楚吗?提前谢谢!!
嗯,现在我觉得告诉我我做了什么很重要:
我想达到的最终目标是:
我很懒,我不想在python中重写那些c代码(在某些情况下这对我来说非常复杂),所以我只想生成gcc
python可以调用的文件。我按照googleing“python call c”给出了一个例子,这个例子中有两个版本:linux和windows:
示例dll
:
test.c
两个版本: 1,在linux下编译
#include <windows.h>
BOOL APIENTRY
DllMain(HANDLE hModule, DWORD dwReason, LPVOID lpReserved) {
return TRUE;
}
__declspec(dllexport) int
multiply(int num1, int num2) {
return num1 * num2;
}
我在我的vista系统上用cygwin做过,它工作正常; :)
2,在windows下编译:
gcc -c -fPIC test.c
gcc -shared test.o -o test.so
我在windows命令行提示符下使用了cl,它不起作用!
这些是python代码:
cl -LD test.c -test.dll
有人可以尝试这个并告诉我你得到了什么吗?谢谢!
答案 0 :(得分:2)
您将找到Microsoft的C ++编译器here的命令行选项。
考虑cl的以下开关:
/nologo /GS /fp:precise /Zc:forScope /Gd
...并使用
链接您的文件/NOLOGO /OUT:"your.dll" /DLL <your lib files> /SUBSYSTEM:WINDOWS /MACHINE:X86 /DYNAMICBASE
请详细了解这些选项的含义,我只列出了常见的选项。尽管如此,你应该知道它们的效果,所以尽量避免复制和粘贴,并确保它真的是你需要的 - 上面链接的文档将对你有所帮助。这只是我经常使用的设置。
请注意,您始终可以打开Visual Studio,配置构建选项,并从项目配置对话框中复制命令行调用。
修改强> 好的,这里有一些更多的建议,考虑到您在原始问题中编辑的新信息。我将简单DLL的示例代码粘贴到源文件中,并进行了两处更改:
#include <windows.h>
BOOL APIENTRY DllMain(HANDLE hModule, DWORD dwReason, LPVOID lpReserved)
{
return TRUE;
}
extern "C" __declspec(dllexport) int __stdcall multiply(int num1, int num2)
{
return num1 * num2;
}
首先,我通常希望从DLL导出的函数使用stdcall调用约定,因为它在Windows中很常见,并且有些语言本身无法处理cdecl,因为它们只知道stdcall。所以这是我做的一个改变。
第二,为了使出口更加友好,我指定了外部“C”来摆脱name mangling。然后我继续从命令行编译代码,如下所示:
cl /nologo /GS /Zc:forScope /Gd c.cpp /link /OUT:"foobar.dll" /DL kernel32.lib /SUBSYSTEM:WINDOWS /MACHINE:X86
如果您使用Visual Studio工具集中的DUMPBIN工具,则可以检查DLL以获取导出:
dumpbin /EXPORTS foobar.dll
看到这样的东西......
ordinal hint RVA name
1 0 00001010 ?multiply@@YGHHH@Z
...你可以注意到导出的名称被破坏了。您通常需要明确的导出名称,因此要么使用DEF文件指定更多详细信息的导出,要么使用上面的快捷方式。
之后,我最终得到了一个DLL,我可以像这样加载到Python中:
In [1]: import ctypes
In [2]: dll = ctypes.windll.LoadLibrary("foobar.dll")
In [3]: dll.multiply
Out[3]: <_FuncPtr object at 0x0928BEF3>
In [4]: dll.multiply(5, 5)
Out[4]: 25
请注意,我在这里使用ctypes.windll,这意味着stdcall。