C++ dll動態程式庫建置架構筆記(CMake build) -3 建立兩層(多層)dll程式

寫這系列筆記主要就是為了要記錄"如何建立多層 dll 程式"的做法而生,網路上看到很少有人說明 dll 去使用 dll 的做法怎麼做,也可能沒輸入到對的關鍵字,雖然其實學會編譯 dll 及使用執行程式測試做出來的 dll,就可能已經大概知道怎麼建立兩層以上的 dll,但我本人就是沒有那個慧根,也可能是因為我一開始是學 LoadLibraryA() 匯入 dll 檔的作法,以至於覺得第二層也是要這樣讀取很複雜,為了探討怎麼輕鬆的做出多層 dll 程式,才有這篇文章。

一、架構說明

Dll_1Layer_math.dll 內容:
建立一個簡單的 dll 數學運算程式,加減乘除等...。
Dll_2Layer_tool.dll 內容:
重新建立函數名稱,使用 Dll_1Layer_math.dll 內函數。
test.exe 內容:
測試 Dll_2Layer_tool.dll 內的函數。

編譯順序:
Dll_1Layer_math.dll → Dll_2Layer_tool.dll → test.exe 

二、建議作法

學習了兩種匯入 dll 的方式後,我發現使用 LoadLibraryA() 比較繁瑣,在重寫函數名稱時容易出錯,修改上也比較麻煩,所以我覺得在必要時才去使用這個做法。

Dll_2Layer_tool.dll → test.exe:
建議兩種做法都可以:1. LoadLibraryA() 2. header.h+.lib+.dll

Dll_1Layer_math.dll → Dll_2Layer_tool.dll:
建議做法 header.h+.lib+.dll

三、實作Dll_2Layer_tool.dll

Dll_1Layer_math.dll 的實作我寫在第一篇文章

檔案結構:
根目錄
├─common
│  └─SVdef.h
├─Dll_2Layer
│  ├─main
│  │  ├─test.cpp
│  │  └─CMakeFiles.txt
│  ├─tool
│  │  ├─include
│  │  │  └─tool_API.h
│  │  └─src
│  │     └─tool_API.cpp
│  └─CMakeFiles.txt
└─CMakeFiles.txt
重新建立函數名稱。
這之前說明過 SV_EXTERN_C → extern "C",SV_EXPORTS → __declspec(dllexport)。
Dll_2Layer\tool\include\tool_API.h
#ifndef TOOL_API_H_
#define TOOL_API_H_

#include "SVdef.h"

SV_EXTERN_C SV_EXPORTS int tool_Add(int a, int b);
SV_EXTERN_C SV_EXPORTS int tool_Subtraction(int a, int b);
SV_EXTERN_C SV_EXPORTS int tool_Multiply(int a, int b);

#endif //TOOL_API_H_
在function內使用my_math.h的函數。
Dll_2Layer\tool\src\tool_API.cpp
#include "tool_API.h"
#include "my_math.h"

int tool_Add(int a, int b)
{
    return Add(a,b);
}
int tool_Subtraction(int a, int b)
{
    return Subtraction(a,b);
}
int tool_Multiply(int a, int b)
{
    return Multiply(a,b);
}
匯入 my_math.h,宣告 define EXPORT_API,連結 Dll_1Layer_math.lib
Dll_2Layer\tool\CMakeLists.txt
set (THE_MODULE "Dll_2Layer_tool")
set (Lib_project "Dll_1Layer_math") # connect Dll_1Layer_math.lib

# include header
INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/Dll_1Layer/math/include)
INCLUDE_DIRECTORIES(./include)

# output Dll_2Layer_tool.lib Dll_2Layer_tool.dll
ADD_LIBRARY(${THE_MODULE} SHARED src/tool_API.cpp)
target_compile_definitions(${THE_MODULE} PRIVATE EXPORT_API) # c++ define EXPORT_API
TARGET_LINK_LIBRARIES(${THE_MODULE} ${Lib_project})

四、實作執行程式test.cpp

我這裡使用 header.h+.lib+.dll 作法
Dll_2Layer\main\test.cpp
#include <stdio.h>
#include "tool_API.h"

int main()
{
    int a = 10;
    int b = 20;

    int res = tool_Add(a,b);
    printf("tool_Add %d\n", res);

    res = tool_Subtraction(a,b);
    printf("tool_Subtraction %d\n", res);

    res = tool_Multiply(a,b);
    printf("tool_Multiply %d\n", res);

    return 0;
}
匯入 tool_API.h,連結 Dll_2Layer_tool.lib
Dll_2Layer\main\CMakeLists.txt
set (THE_MODULE "Dll_2Layer_main")
set (Lib_project "Dll_2Layer_tool") # connect Dll_2Layer_tool.lib

# include header
INCLUDE_DIRECTORIES(../tool/include)

# output Dll_2Layer_main.exe
ADD_EXECUTABLE(${THE_MODULE} test.cpp)
TARGET_LINK_LIBRARIES(${THE_MODULE} ${Lib_project})

留言

這個網誌中的熱門文章

C# 模擬鍵盤滑鼠控制電腦

python nn 聲音辨識 -1 傅立葉轉換

android 定時通知(永久長期的) 本篇只講AlarmManager使用

raspberrypi 開機自動執行程式 與 在terminal開啟第二個terminal執行python

python opencv 基本讀取、轉換、顯示、儲存等