hello world之 在windows建立dll檔

前言

使用dll檔,有兩種,一種是要用lib加入編譯的,一種不用。
在此,是介紹不用的那種。
另外,這次的dll包裝是包裝成c語言的呼叫型式。

使用工具: visual studio 2005
環境: Windows 8

開始囉!

要準備兩個專案檔,一個是dll檔,一個是執行檔
dll檔為外掛程式,執行檔為核心程式,核心程式初始化時,dll檔就可以載進來當作是核心程式的外掛。

先說說dll檔

新增專案[1]
Project type: Win32 Console Application
Application type: DLL
Additional options: Empty project

dll_hello_world.h
這是用來設定共用介面的檔案,必須要加到核心程式的專案中,一起編譯。
extern "C" __declspec(dllexport) 
const char* HelloWorld();

dll_hello_world.cpp
 #include "dll_hello_world.h"  

__declspec(dllexport)
const char* HelloWorld()
{
    return "hello world";
}

再看看執行檔

新增專案[1]
Project type: Win32 Console Application
Application type: Console Application
Additional options: Empty project

這段程式碼,是參考[1]修改而來的,對於dll檔,我又再包了一層dll檔的類別。
每一步的行為都進行了分類,方便讀者對於dll檔的行為做區分。

main.cpp
#include "dll_hello_world.h"
#include <exception>
#include <string>
#include <iostream>
#include <Windows.h>

class DllFile
{
    typedef const char *(*CreateCallBack)();  
    CreateCallBack call_function;
    HINSTANCE dll_core;
public:
    DllFile(const std::string &dll_filename)
    try
    {
        dll_core = LoadLibrary(dll_filename.data()); //[2]
        if (dll_core == 0)
        {
            throw std::exception("load Dll not success.");
        }
    }
    catch(std::exception &e)
    {
        FreeLibrary(dll_core);
        throw ;
    }
    catch(...)
    {
        FreeLibrary(dll_core);
        throw std::exception("initial DLL false.");
    }

    ~DllFile()
    {
        FreeLibrary(dll_core);
    }

    const char* CallFunction(const std::string &symbolname)
    {
        call_function = (CreateCallBack)GetProcAddress(dll_core, symbolname.data());  
        if (call_function != 0)
        {
            return call_function();
        }
        else
        {  
            FreeLibrary(dll_core);
            throw std::exception("can not function of DLL.");
        } 
    }
};


int main()
{  
    try
    {
        DllFile demo_file("dllfile.dll");
        std::cout << demo_file.CallFunction("HelloWorld") << std::endl;
    }
    catch(std::exception &e)
    {
        std::cout << "ERROR:" << e.what() << std::endl;
    }
    system("PAUSE");

    return 0;  
}

可能會遇到的問題


  • 問題: error C2664: 'LoadLibraryW' : cannot convert parameter 1 from 'const char *' to 'LPCWSTR'
    解法: 設定專案檔的字集為Use Multi-Byte Character Set(不要用Unicode)

程式碼

放在: github (已固定版本)

參考資料

[1] [C++ 小學堂] 如何建立 export 的 dll 與如何動態呼叫 export 的 dll
[2] (原创)一个简洁通用的调用DLL函数的帮助类
[3] Error C2664 LoadLibraryW cannot convert parameter to LPCWSTR

沒有留言:

張貼留言

(什麼是留言欄訊息?)