http://blog.csdn.net/hong201/article/details/4499998
2009-08-30 17:04
360人阅读
评论(0)
1.dll生成
dll的入口如下,就像应用程序的main函数一样,其中DLL_PROCESS_ATTACH是dll被调用的执行处理,DLL_PROCESS_DETACH是被卸载的时候的调用。
BOOLAPIENTRY DllMain(HANDLEhModule,
DWORDul_reason_for_call,
LPVOIDlpReserved
)
{
switch(ul_reason_for_call)
{
caseDLL_PROCESS_ATTACH:
caseDLL_THREAD_ATTACH:
caseDLL_THREAD_DETACH:
caseDLL_PROCESS_DETACH:
break;
}
returnTRUE;
}
先定义一些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
classDLLTEST_API CDllCase
{
public:
CDllCase();
virtual~CDllCase();
public:
intGetSub(intnLeft,intnRight);
voidGetStr(char* pszDst,constchar* pszSrc);
};
DLLTEST_API_C intg_nDlltest;
DLLTEST_API_C intfnDlltest(intnLeft,intnRight);
DLLTEST_API_C voidfnGetStr(char* pszDst,constchar* pszSrc);
该头文件的实现文件,简单的一些例子
#dllcase.cpp
intg_nDlltest = 0;
intfnDlltest(intnLeft,intnRight)
{
g_nDlltest = nLeft + nRight;
returng_nDlltest;
}
voidfnGetStr(char* pszDst,constchar* pszSrc)
{
::strcpy(pszDst, pszSrc);
}
CDllCase::CDllCase()
{
}
CDllCase::~CDllCase()
{
}
intCDllCase::GetSub(intnLeft,intnRight)
{
returnnLeft - nRight;
}
voidCDllCase::GetStr(char* pszDst,constchar* 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 <
std::cout <
CDllCase c;
std::cout <
char* pszSrc ="Hello dll.";
charszDst[sizeof(pszSrc) + 1] = {0x00};
c.GetStr(szDst, pszSrc);
std::cout <
2.2C++调用,显示调用,只需要dll文件就可以了,放置在应用程序目录下
typedefint* nDlltest;
typedefint(*AddFunc)(int,int);
voidusedllShow()
{
AddFunc _AddFunc;
HINSTANCEhInstLibrary = ::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 <
std::cout <
::FreeLibrary(hInstLibrary);
}
i
2.2 python调用dll文件
在其他语言中只能用显示调用了,其他语言没有办法和C++头文件交互。
importctypes
defdll_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
defdll_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)
printnRst
if__name__ =='__main__':
dll_read_1("dlltest.dll")
# dll_read_2("dlltest.dll")