1.前面有介紹動态連結庫和靜态連結庫。
靜态連結庫:建立和使用靜态庫(.lib)
隐式調用dll:VS2008建立DLL,并且使用DLL
2.現在主要講解下顯示調用dll,并且結合共享記憶體
共享記憶體:C/C++ 日常學習總結(第二十二篇)共享記憶體實作C++
3.顯示調用
這種調用需要調用::LoadLibrary()或者類似的函數,用來動态加載連結庫,再使用GetProcAddress()獲得要調用的每個函數的函數指針,使用完畢,調用FreeLibrary()解除安裝dll,
這種方式的調用不需要*.lib檔案,也不需要*.h檔案。但是必須要知道要調用函數的函數原型,以便為GetProcAddress()的傳回值定義相應的函數指針。
建立dll就不用多說,上面連結有介紹。
(1.)Memdll.dll中函數原型:
struct SData
{
int num;
int age;
char name[128];
};
extern "C" __declspec (dllexport) void WriteDataToMem(SData &data,LPCWSTR name)
{
HANDLE hfilemap = NULL;
hfilemap = ::CreateFileMapping(INVALID_HANDLE_VALUE,NULL,PAGE_READWRITE,0,65536,name);
if (NULL==hfilemap)
{
return;
}
PVOID pview = NULL;
pview = ::MapViewOfFile(hfilemap,FILE_MAP_ALL_ACCESS,0,0,1024);
if (NULL==pview)
{
return;
}
memcpy_s(pview,1024,(&data),sizeof(SData));
}
extern "C" __declspec (dllexport) SData* ReadDataFromMem(LPCWSTR name)
{
HANDLE hfilemap = NULL;
hfilemap = ::OpenFileMapping(FILE_MAP_READ,FALSE,name);
if (NULL==hfilemap)
{
return NULL;
}
PVOID pview = NULL;
pview = ::MapViewOfFile(hfilemap,FILE_MAP_READ,0,0,1024);
if (NULL == pview)
{
return NULL;
}
SData *data = (SData*)pview;
return data;
}
(2.)應用程式中的調用:
struct SData
{
int num;
int age;
char name[128];
};
typedef void (*WriteDataToMem)(SData &data,LPCWSTR name);
typedef SData* (*ReadDataFromMem)(LPCWSTR name);
結構體原型是必須和dll檔案中相同,然後是定義函數指針,也就是事先必須知道函數原型的原因。 形參不可少。
int main()
{
WriteDataToMem _write;
ReadDataFromMem _read;
hmodule = ::LoadLibrary("MemDll.dll");
if (NULL==hmodule)
{
::FreeLibrary(hmodule);
return 0;
}
_write = (WriteDataToMem)GetProcAddress(hmodule,"WriteDataToMem");
if (NULL==_write)
{
return 0;
}
SData data;
data.age = 100;
data.num = 8080;
strcpy(data.name,"周傑倫");
LPCWSTR name = (LPCWSTR)("password");
_write(data,name);
_read = (ReadDataFromMem)GetProcAddress(hmodule,"ReadDataFromMem");
if (NULL==_read)
{
return 0;
}
SData *dataout = NULL;
dataout = _read(name);
return 0;
}
【說明】:共享記憶體用于程序之間,上述代碼隻為了測試友善,寫在了同一個程序内。
上面main函數中,先加載dll,然後獲得函數指針,然後直接調用即可。