C/C++高階語法:函式指標及其應用,動態連結庫,正向呼叫
阿新 • • 發佈:2019-01-10
1、在介紹正向呼叫之前,先講一講動態連結庫的知識:
1)、 動態連結庫 DLL,即Dynamic Link Library,在理解動態連結庫的時候,我們可以把它理解為一個包含變數,函式或是類的集合,我們可以通過一定的方式來呼叫包含在這個集合中的那些變數,函式或是類。
2)、動態連結庫的建立與編譯器或是程式語言沒有關係,我們只需要遵守特定的約定便可以建立動態連結庫。
3)、動態連結庫隨處可見,我們不要因為沒有用過而感到陌生。
2、知道了動態連結庫是何種怪我之後,我們自己來建立一個動態連結庫。
這裡使用codeblocks 來建立,(同樣可以使用vs等軟體)。
新增標頭檔案:
#ifndef __TEST_H__ #define __TEST_H__ #include <windows.h> /* To use this exported function of dll, include this header * in your project. */ #ifdef BUILD_DLL #define DLL_EXPORT __declspec(dllexport) #else #define DLL_EXPORT __declspec(dllimport) #endif char* DLL_EXPORT FindKey(const char (*KeyValue)[40] /*in*/, const char *KeyBuf /*in*/); int DLL_EXPORT GetKeyValue(const char (*KeyValue)[40] /*in*/, const char *KeyBuf /*in*/, char *ValueBuf /*out*/, int * ValueLenth /*out*/); int DLL_EXPORT TrimSpace(const char *strInput /*in*/, char *strOut /*out*/); #endif // __TEST_H__
新增實現檔案:
在實現檔案中新增 #include "Test.h"
然後編譯即可生成。此時在bin/debug目錄下有三個檔案,如下圖所示: 當然在 VS之下會有所不同,在這裡也展示一下VS之下生成的檔案:char* DLL_EXPORT FindKey(const char (*KeyValue)[40] /*in*/, const char *KeyBuf /*in*/) { ...... } int DLL_EXPORT GetKeyValue(const char (*KeyValue)[40] /*in*/, const char *KeyBuf /*in*/, char *ValueBuf /*out*/, int * ValueLenth /*out*/) { ...... } int DLL_EXPORT TrimSpace(const char *strInput /*in*/, char *strOut /*out*/) { ...... }
這裡會多一個Object File Library 檔案,這是對dll資源的描述檔案。
3、使用dll檔案,函式指標的正向呼叫
上面講了那麼多,就是為了使用函式指標,這也是函式指標在實際程式設計中的一種應用,所以希望大家多加練習,把這種方法掌握。
附上原始碼以及測試的結果;
#include <Windows.h>
#include <stdio.h>
//定義一個函式指標型別
typedef int (*pGetKeyValue)(const char (*KeyValue)[40] /*in*/,\
const char *KeyBuf /*in*/, char *ValueBuf /*out*/, int * ValueLenth /*out*/);
void main()
{
const char KeyValue[10][40] = { "key1= today",
"key2 = is ",
"key3= a ",
"key4 = very ",
"key5= beautiful",
"key6= and ",
"key7=very",
"key8= important",
"key9= nice ",
"key10= day "
};
char KeyBuf[10] = { 0 };
char ValueBuf[40] = { 0 };
int nLenth = 0;
int ret = 0;
HANDLE m_handle;
pGetKeyValue getKeyValue = NULL;
m_handle = LoadLibrary(TEXT("DllNew.dll"));
if(NULL!= m_handle)
{
getKeyValue = (pGetKeyValue)GetProcAddress(m_handle,"GetKeyValue");
}
printf("Pleade Input the KeyBuf:");
gets(KeyBuf);
if(NULL!=getKeyValue)
{
ret = getKeyValue(KeyValue, KeyBuf, ValueBuf, &nLenth);
}
if (0 != ret)
{
printf("Func_GetKeyValue_error:%d\n", ret);
}
printf("%s\n%s\n%d\n", KeyBuf, ValueBuf, nLenth);
if(NULL != m_handle)
{
FreeLibrary(m_handle);
}
system("pause");
}
測試 key1:
顯示: 鍵key1所對應的鍵值為today,長度為5.
測試其他的:
顯示:鍵maomao 沒有在鍵值陣列中,所以返回一個錯誤程式碼。
5、 對上述程式碼的解釋:
typedef int (*pGetKeyValue)(const char (*KeyValue)[40] /*in*/,\
const char *KeyBuf /*in*/, char *ValueBuf /*out*/, int * ValueLenth /*out*/);
定義一個函式指標型別來,該型別和動態連結庫中的型別一樣,如果還不明白函式型別是什麼,請看函式指標及其應用
然後使用loadlibrary()載入動態連結庫。
m_handle = LoadLibrary(TEXT("DllNew.dll"));
使用 函式指標型別定義一個識別符號來取得函式的地址:
if(NULL!= m_handle)
{
getKeyValue = (pGetKeyValue)GetProcAddress(m_handle,"GetKeyValue");
}
最後要釋放動態連結庫:
if(NULL != m_handle)
{
FreeLibrary(m_handle);
}
6、本次的程式碼量比較長,全部放在文中會顯得拖沓,故需要者可以前去下載原始碼。如果還有什麼不明白的可以相互交流,共同提升。
函式指標的應用待續。。。。。。