如何使用cl命令?

时间:2010-09-09 18:51:33

标签: python c compiler-construction

所有,我发现了一些关于如何在python中调用c文件的信息,在这些例子中:有一个ac文件,其中包含许多其他头文件,这个c文件的最开头是#include Python.h,然后我发现#include Python.h实际上涉及许多其他头文件,例如pystate.hobject.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

有人可以尝试这个并告诉我你得到了什么吗?谢谢!

1 个答案:

答案 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。