http://blog.csdn.net/hong201/article/details/4499998
关于dll的介绍可以在这里看到http://support.microsoft.com/kb/815065/zh-cn,这个算是官方解释了。
1.dll生成
dll的入口如下,就像应用程序的main函数一样,其中DLL_PROCESS_ATTACH是dll被调用的执行处理,DLL_PROCESS_DETACH是被卸载的时候的调用。
- BOOL APIENTRY DllMain( HANDLE hModule,
- DWORD ul_reason_for_call,
- LPVOID lpReserved
- )
- {
- switch (ul_reason_for_call)
- {
- case DLL_PROCESS_ATTACH:
- case DLL_THREAD_ATTACH:
- case DLL_THREAD_DETACH:
- case DLL_PROCESS_DETACH:
- break;
- }
- return TRUE;
- }
先定义一些dll导出的接口,__declspec(dllexport)对dll来说,是需要导出的接口,当然了也可以用def文件来定义导出接口;__declspec(dllimport)是对调用该dll的程序来说,是需要导入。
#dllcase.h
- #ifdef DLLTEST_EXPORTS
- #define DLLTEST_API_C extern "C" __declspec(dllexport)
- #define DLLTEST_API __declspec(dllexport)
- #else
- #define DLLTEST_API_C extern "C" __declspec(dllimport)
- #define DLLTEST_API __declspec(dllimport)
- #endif
- class DLLTEST_API CDllCase
- {
- public:
- CDllCase();
- virtual ~CDllCase();
- public:
- int GetSub(int nLeft, int nRight);
- void GetStr(char* pszDst, const char* pszSrc);
- };
- DLLTEST_API_C int g_nDlltest;
- DLLTEST_API_C int fnDlltest(int nLeft, int nRight);
- DLLTEST_API_C void fnGetStr(char* pszDst, const char* pszSrc);
该头文件的实现文件,简单的一些例子
#dllcase.cpp
- int g_nDlltest = 0;
- int fnDlltest(int nLeft, int nRight)
- {
- g_nDlltest = nLeft + nRight;
- return g_nDlltest;
- }
- void fnGetStr(char* pszDst, const char* pszSrc)
- {
- ::strcpy(pszDst, pszSrc);
- }
- CDllCase::CDllCase()
- {
- }
- CDllCase::~CDllCase()
- {
- }
- int CDllCase::GetSub(int nLeft, int nRight)
- {
- return nLeft - nRight;
- }
- void CDllCase::GetStr(char* pszDst, const char* pszSrc)
- {
- ::strcpy(pszDst, pszSrc);
- }
编译完该dll文件之后,dumpbin -exports dlltest.dll,就可以看到该dll导出的接口了。
2.dll调用
2.1 C++调用,隐式调用
需要dll文件,lib文件,头文件
包含头文件,#include "DllCase.h",链接lib文件#pragma comment(lib, "dlltest.lib"),dll文件一般和应用程序放在同一个目录
- std::cout << "fnDlltest(1, 2): " << fnDlltest(1, 2) << std::endl;
- std::cout << "g_nDlltest: " << g_nDlltest << std::endl;
- CDllCase c;
- std::cout << "CDllCase::GetSub(2,8): " << c.GetSub(2,8) << std::endl;
- char* pszSrc = "Hello dll.";
- char szDst[sizeof(pszSrc) + 1] = {0x00};
- c.GetStr(szDst, pszSrc);
- std::cout << "CDllCase::GetStr: " << szDst << std::endl;
2.2C++调用,显示调用,只需要dll文件就可以了,放置在应用程序目录下
- typedef int* nDlltest;
- typedef int (*AddFunc)(int, int);
- void usedllShow()
- {
- AddFunc _AddFunc;
- HINSTANCE hInstLibrary = ::LoadLibrary("dlltest.dll");
- if (NULL == hInstLibrary)
- {
- ::FreeLibrary(hInstLibrary);
- return;
- }
- _AddFunc = (AddFunc)::GetProcAddress(hInstLibrary, "fnDlltest");
- nDlltest n = (nDlltest)::GetProcAddress(hInstLibrary, "g_nDlltest");
- if (NULL == _AddFunc || NULL == n)
- {
- ::FreeLibrary(hInstLibrary);
- return;
- }
- std::cout << "fnDlltest(1, 2): " << _AddFunc(1, 12) << std::endl;
- std::cout << "g_nDlltest: " << *n << std::endl;
- ::FreeLibrary(hInstLibrary);
- }
- i
2.2 python调用dll文件
在其他语言中只能用显示调用了,其他语言没有办法和C++头文件交互。
- import ctypes
- def dll_read_1(dll_name):
- ''''' __cdecl'''
- dll = ctypes.cdll.LoadLibrary(dll_name)
- print "first dll func [fnDlltest]", dll.fnDlltest(2, 8)
- s1 = "Hello, python and C++."
- s2 = ctypes.create_string_buffer("", len(s1))
- dll.fnGetStr(s2, s1)
- print "second dll func [fnGetStr]", s2.value
- def dll_read_2(dll_name):
- '''''__stdcall '''
- dll = ctypes.windll.LoadLibrary(dll_name)
- test = dll.fnDlltest
- test.argtypes = [ctypes.c_int, ctypes.c_int]
- test.restypes = ctypes.c_int
- nRst = test(1, 3)
- print nRst
- if __name__ == '__main__':
- dll_read_1("dlltest.dll")
- # dll_read_2("dlltest.dll")