This article mainly introduces how Python calls the CC ++ dynamic link library, for more information about how to call the C/C ++ DLL dynamic link library in Python, see the following example:
Example 1:
First, create a DLL project (in this example, the environment is VS 2005). The header file:
//hello.h#ifdef EXPORT_HELLO_DLL#define HELLO_API __declspec(dllexport)#else#define HELLO_API __declspec(dllimport)#endifextern "C"{ HELLO_API int IntAdd(int , int);}
CPP file:
//hello.cpp#define EXPORT_HELLO_DLL#include "hello.h"HELLO_API int IntAdd(int a, int b){ return a + b;}
Note:
(1) find out whether the _ cdecl or _ stdcall function is used in the function call conventions during compilation. because according to the function call conventions in the DLL, Python will use the corresponding function to load the DLL.
(2) if a C ++ project is used, the exported interface must be extern "C" so that the exported function can be identified in python.
In my project, the _ cdecl function call convention is used to compile the link to generate hello. dll, and then the ctypes library is used in Python to load hello. dll and call the function:
from ctypes import *dll = cdll.LoadLibrary('hello.dll');ret = dll.IntAdd(2, 4);print ret;
Now, the first small example has been completed. you can try it yourself.
Example 2:
Example 1 is a "hello world" program. in actual use, more data structures and strings need to be transmitted to meet our needs. This example shows how to pass the data structure parameters and how to obtain the return value through the data structure.
First, compile the header file in the DLL project:
//hello.h#ifdef EXPORT_HELLO_DLL#define HELLO_API __declspec(dllexport)#else#define HELLO_API __declspec(dllimport)#endif#define ARRAY_NUMBER 20#define STR_LEN 20struct StructTest{ int number; char* pChar; char str[STR_LEN]; int iArray[ARRAY_NUMBER];};extern "C"{ //HELLO_API int IntAdd(int , int); HELLO_API char* GetStructInfo(struct StructTest* pStruct);}
The CPP file is as follows:
//hello.cpp#include
#define EXPORT_HELLO_DLL#include "hello.h"HELLO_API char* GetStructInfo(struct StructTest* pStruct){ for (int i = 0; i < ARRAY_NUMBER; i++) pStruct->iArray[i] = i; pStruct->pChar = "hello python!"; strcpy (pStruct->str, "hello world!"); pStruct->number = 100; return "just OK";}
The GetStructInfo function passes a StructTest pointer, assigns values to the attributes of the object, and returns "just OK ".
Compile the Python call code as follows. first, inherit Structure in Python to construct a consistent data Structure StructTest as in c dll, and then set the parameter type and return value type of the GetStructInfo function, finally, create a StructTest object, convert it to a pointer as a parameter, call the GetStrcutInfo function, and check whether the call is successful by outputting the value of the data structure:
from ctypes import *ARRAY_NUMBER = 20;STR_LEN = 20;#define typeINTARRAY20 = c_int * ARRAY_NUMBER;CHARARRAY20 = c_char * STR_LEN;#define structclass StructTest(Structure): _fields_ = [ ("number", c_int), ("pChar", c_char_p), ("str", CHARARRAY20), ("iArray", INTARRAY20) ]#load dll and get the function objectdll = cdll.LoadLibrary('hello.dll');GetStructInfo = dll.GetStructInfo;#set the return typeGetStructInfo.restype = c_char_p;#set the argtypesGetStructInfo.argtypes = [POINTER(StructTest)];objectStruct = StructTest();#invoke api GetStructInforetStr = GetStructInfo(byref(objectStruct));#check resultprint "number: ", objectStruct.number;print "pChar: ", objectStruct.pChar;print "str: ", objectStruct.str;for i,val in enumerate(objectStruct.iArray): print 'Array[i]: ', val;print retStr;
Summary:
1. an error occurs when 32-bit DLL is loaded using 64-bit Python.
2. the above are just some test programs. try to use "try Again T" to handle exceptions when writing Python.
3. Note the byte alignment problem during interaction between Python and c dll.
4. the function of the ctypes Library remains to be explored.