当前位置:编程学习 > C/C++ >>

如何用 C++ 为 Python 写 dll

1. 先新建一个名为 hello.cpp 的 C++ 源文件:

Cpp代码   
#include <stdio.h>   
  
#define DLLEXPORT extern "C" __declspec(dllexport)   
  
DLLEXPORT int __stdcall hello()   
{   
    printf("Hello world!\n");   
    return 0;   
}  
#include <stdio.h>

#define DLLEXPORT extern "C" __declspec(dllexport)

DLLEXPORT int __stdcall hello()
{
    printf("Hello world!\n");
    return 0;

2. 编译成 dll 文件:


Cpp代码   
cl /LD hello.cpp  
cl /LD hello.cpp 

注意, 这里的参数是 /LD, 而不是 /DL。


3. 编写一个名为 hello.py 的 python 文件:


Python代码   
# coding: utf-8   
  
import os   
import ctypes   
  
CUR_PATH = os.path.dirname(__file__)   
  
if __name__ == '__main__':   
    print 'starting...'  
    dll = ctypes.WinDLL(os.path.join(CUR_PATH, 'hello.dll'))   
    dll.hello()  
# coding: utf-8

import os
import ctypes

CUR_PATH = os.path.dirname(__file__)

if __name__ == '__main__':
    print 'starting...'
    dll = ctypes.WinDLL(os.path.join(CUR_PATH, 'hello.dll'))
    dll.hello()


4. 输出为:

 

Python代码   
starting...   
Hello world!  
starting...
Hello world!


需要注意的地方:
1. C++ 的 dll 中的接口函数必须以 extern "C" __declspec(dllexport) 为前缀, C 的以 __declspec(dllexport) 为前缀。
否则会报错:

 

Python代码   
Traceback (most recent call last):   
  File "hello.py", line 12, in <module>   
    dll.hello()   
  File "C:\Python25\lib\ctypes\__init__.py", line 361, in __getattr__   
    func = self.__getitem__(name)   
  File "C:\Python25\lib\ctypes\__init__.py", line 366, in __getitem__   
    func = self._FuncPtr((name_or_ordinal, self))   
AttributeError: function 'hello' not found  
Traceback (most recent call last):
  File "hello.py", line 12, in <module>
    dll.hello()
  File "C:\Python25\lib\ctypes\__init__.py", line 361, in __getattr__
    func = self.__getitem__(name)
  File "C:\Python25\lib\ctypes\__init__.py", line 366, in __getitem__
    func = self._FuncPtr((name_or_ordinal, self))
AttributeError: function 'hello' not found  www.zzzyk.com


2. 是使用 ctypes.CDLL 还是 ctypes.WinDLL 呢?
反正我是分不清,所以在 dll 中的接口函数中显式地加上了 __stdcall. 似乎一个是 caller 清栈,另外一个是 callee 清。

MSDN 中关于 __stdcall, __cdecl 的介绍:
__cdecl:
http://msdn.microsoft.com/en-us/library/zkwh89ks(VS.80).aspx
This is the default calling convention for C and C++ programs. Because the stack is cleaned up by the caller, it can do vararg functions. The __cdecl calling convention creates larger executables than __stdcall, because it requires each function call to include stack cleanup code. The following list shows the implementation of this calling convention.

__stdcall:
http://msdn.microsoft.com/en-us/library/zxk0tw93(VS.71).aspx
The __stdcall calling convention is used to call Win32 API functions. The callee cleans the stack, so the compiler makes vararg functions __cdecl.

补充:软件开发 , C++ ,
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,