1. 程式人生 > >C/C++高階語法:函式指標及其應用,動態連結庫,正向呼叫

C/C++高階語法:函式指標及其應用,動態連結庫,正向呼叫

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"

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*/)
{
   ......
}


然後編譯即可生成。此時在bin/debug目錄下有三個檔案,如下圖所示: 當然在 VS之下會有所不同,在這裡也展示一下VS之下生成的檔案:

這裡會多一個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、本次的程式碼量比較長,全部放在文中會顯得拖沓,故需要者可以前去下載原始碼。如果還有什麼不明白的可以相互交流,共同提升。

      函式指標的應用待續。。。。。。