python下如何调用dll

http://blog.csdn.net/hong201/article/details/4499998


dll调用的来龙去脉

分类: C++ Python 360人阅读 评论(0) 收藏 举报
dll api thread python null c

 关于dll的介绍可以在这里看到http://support.microsoft.com/kb/815065/zh-cn,这个算是官方解释了。

 

1.dll生成

dll的入口如下,就像应用程序的main函数一样,其中DLL_PROCESS_ATTACH是dll被调用的执行处理,DLL_PROCESS_DETACH是被卸载的时候的调用。

 

[cpp] view plain copy
  1. BOOL APIENTRY DllMain( HANDLE hModule,   
  2.                        DWORD  ul_reason_for_call,   
  3.                        LPVOID lpReserved  
  4.                      )  
  5. {  
  6.     switch (ul_reason_for_call)  
  7.     {  
  8.         case DLL_PROCESS_ATTACH:  
  9.         case DLL_THREAD_ATTACH:  
  10.         case DLL_THREAD_DETACH:  
  11.         case DLL_PROCESS_DETACH:  
  12.             break;  
  13.     }  
  14.     return TRUE;  
  15. }  

 

 

先定义一些dll导出的接口,__declspec(dllexport)对dll来说,是需要导出的接口,当然了也可以用def文件来定义导出接口;__declspec(dllimport)是对调用该dll的程序来说,是需要导入。

 #dllcase.h

 

[cpp] view plain copy
  1. #ifdef DLLTEST_EXPORTS  
  2. #define DLLTEST_API_C extern "C" __declspec(dllexport)  
  3. #define DLLTEST_API __declspec(dllexport)  
  4. #else  
  5. #define DLLTEST_API_C extern "C" __declspec(dllimport)  
  6. #define DLLTEST_API __declspec(dllimport)  
  7. #endif  
  8.   
  9. class DLLTEST_API CDllCase    
  10. {  
  11. public:  
  12.     CDllCase();  
  13.     virtual ~CDllCase();  
  14.   
  15. public:  
  16.     int GetSub(int nLeft, int nRight);  
  17.     void GetStr(char* pszDst, const char* pszSrc);  
  18.   
  19. };  
  20.   
  21. DLLTEST_API_C int g_nDlltest;  
  22.   
  23. DLLTEST_API_C int fnDlltest(int nLeft, int nRight);  
  24. DLLTEST_API_C void fnGetStr(char* pszDst, const char* pszSrc);  

 

该头文件的实现文件,简单的一些例子

#dllcase.cpp

[cpp] view plain copy
  1. int g_nDlltest = 0;  
  2.   
  3. int fnDlltest(int nLeft, int nRight)  
  4. {  
  5.     g_nDlltest = nLeft + nRight;  
  6.     return g_nDlltest;  
  7. }  
  8.   
  9. void fnGetStr(char* pszDst, const char* pszSrc)  
  10. {  
  11.     ::strcpy(pszDst, pszSrc);  
  12. }  
  13.   
  14. CDllCase::CDllCase()  
  15. {  
  16.   
  17. }  
  18.   
  19. CDllCase::~CDllCase()  
  20. {  
  21.   
  22. }  
  23.   
  24. int CDllCase::GetSub(int nLeft, int nRight)  
  25. {  
  26.     return nLeft - nRight;  
  27. }  
  28.   
  29. void CDllCase::GetStr(char* pszDst, const char* pszSrc)  
  30. {  
  31.     ::strcpy(pszDst, pszSrc);  
  32. }  

 

编译完该dll文件之后,dumpbin -exports dlltest.dll,就可以看到该dll导出的接口了。

 

2.dll调用

2.1 C++调用,隐式调用

需要dll文件,lib文件,头文件

包含头文件,#include "DllCase.h",链接lib文件#pragma comment(lib, "dlltest.lib"),dll文件一般和应用程序放在同一个目录

 

[cpp] view plain copy
  1. std::cout << "fnDlltest(1, 2): " << fnDlltest(1, 2) << std::endl;  
  2. std::cout << "g_nDlltest: " << g_nDlltest << std::endl;  
  3.   
  4. CDllCase c;  
  5. std::cout << "CDllCase::GetSub(2,8): " << c.GetSub(2,8) << std::endl;  
  6.   
  7. char* pszSrc = "Hello dll.";  
  8. char szDst[sizeof(pszSrc) + 1] = {0x00};  
  9. c.GetStr(szDst, pszSrc);  
  10.   
  11. std::cout << "CDllCase::GetStr: " << szDst << std::endl;  

 

2.2C++调用,显示调用,只需要dll文件就可以了,放置在应用程序目录下

[cpp] view plain copy
  1. typedef int* nDlltest;  
  2. typedef int (*AddFunc)(intint);  
  3.   
  4. void usedllShow()  
  5. {  
  6.     AddFunc _AddFunc;  
  7.     HINSTANCE hInstLibrary = ::LoadLibrary("dlltest.dll");  
  8.     if (NULL == hInstLibrary)  
  9.     {  
  10.         ::FreeLibrary(hInstLibrary);  
  11.         return;  
  12.     }  
  13.       
  14.     _AddFunc = (AddFunc)::GetProcAddress(hInstLibrary, "fnDlltest");  
  15.     nDlltest n = (nDlltest)::GetProcAddress(hInstLibrary, "g_nDlltest");  
  16.     if (NULL == _AddFunc || NULL == n)  
  17.     {  
  18.         ::FreeLibrary(hInstLibrary);  
  19.         return;  
  20.     }  
  21.       
  22.     std::cout << "fnDlltest(1, 2): " << _AddFunc(1, 12) << std::endl;  
  23.     std::cout << "g_nDlltest: " << *n << std::endl;  
  24.   
  25.     ::FreeLibrary(hInstLibrary);  
  26.   
  27. }  
  28. i  

 

2.2 python调用dll文件

在其他语言中只能用显示调用了,其他语言没有办法和C++头文件交互。

[python] view plain copy
  1. import ctypes  
  2.   
  3. def dll_read_1(dll_name):  
  4.     ''''' __cdecl'''  
  5.     dll = ctypes.cdll.LoadLibrary(dll_name)  
  6.     print "first dll func [fnDlltest]", dll.fnDlltest(28)  
  7.       
  8.     s1 = "Hello, python and C++."  
  9.     s2 = ctypes.create_string_buffer("", len(s1))  
  10.     dll.fnGetStr(s2, s1)  
  11.     print "second dll func [fnGetStr]", s2.value  
  12.   
  13. def dll_read_2(dll_name):  
  14.     '''''__stdcall '''  
  15.     dll = ctypes.windll.LoadLibrary(dll_name)  
  16.   
  17.     test  = dll.fnDlltest  
  18.     test.argtypes = [ctypes.c_int, ctypes.c_int]  
  19.     test.restypes = ctypes.c_int  
  20.     nRst = test(13)  
  21.     print nRst  
  22.    
  23. if __name__ == '__main__':  
  24.     dll_read_1("dlltest.dll")      
  25. #    dll_read_2("dlltest.dll") 

你可能感兴趣的:(C++,python)