簡體   English   中英

將目前為獨立可執行文件開發的C ++項目轉換為DLL

[英]Converting a C++ project so far developed as standalone executable into a DLL

(我在Windows 7 64位計算機上使用Microsoft Visual Studio 2010)

我開發了一個C ++程序,它更像是一個隨着時間的推移變得非常復雜的庫。 它現在作為一個簡單的可執行程序工作,但我想將其轉換為DLL,以便其他程序可以輕松訪問其功能。

我對使用DLL沒有任何經驗,但我想避免在此過程中進行大量額外的工作和代碼更改。

我知道我可以選擇編譯目標為“DLL”,但我覺得單獨不能完成這項工作。

  • 如果我成功將項目編譯成DLL文件,如何從可執行項目中使用其中的函數?

  • 我可以避免使用_dllexport並導入每個名稱的每個函數嗎?

  • 如何靜態鏈接DLL,以及它的(dis)優勢是什么?

老實說,我會看看DLL導出文檔,並選擇最適合您的導出方法。 在任何情況下,您都可以通過客戶端應用程序中的名稱簡單地引用導出的函數,就像使用靜態庫一樣。

當您將項目構建為DLL時,IDE將生成

  1. 用於運行時和的DLL文件
  2. 包含導出的函數解析信息的LIB文件 - 這是您鏈接的信息。

根據定義,您不能靜態鏈接DLL(即DYNAMIC鏈接庫) - 而是鏈接到從DLL導出函數的庫,然后DLL在運行時加載,可以在進程啟動時或按需自動加載。 也可以在沒有任何靜態鏈接的情況下完全按需加載DLL(請參閱LoadLibraryEx等)。

既然你正在使用C ++我假設你正在導出類(?)。 在CodeProject上有一個很好的例子 ,它會引導您完成一些選項。 最干凈的是使用抽象接口:

C ++抽象接口(即只包含純虛方法而沒有數據成員的C ++類)試圖充分利用兩個世界:一個獨立於編譯器的對象干凈接口,以及一種方便的面向對象的方法調用方式。 所需要做的就是提供帶有接口聲明的頭文件,並實現一個返回新創建的對象實例的工廠函數。 只有工廠函數必須使用__declspec(dllexport / dllimport)說明符聲明。 該接口不需要任何其他說明符。

抽象接口示例的工作原理示例

您無法靜態鏈接到動態鏈接庫 如果要靜態鏈接,請改為創建.lib。

  • 要使用您的DLL,您必須#include與您的dll / lib關聯的頭文件,並鏈接到與.dll關聯的.lib文件

  • 您需要_ declspec(dllexport)/ _declspec(dllimport)來指示您要導出/導入dll的內容。 這可以如下容易地完成

  #ifdef FOO_EXPORTS #define EXPORT_ME __declspec(dllexport) #else #define IMPORT_ME __declspec(dllimport) #endif 

在您的DLL的標題中,您只需#define FOO_EXPORTS並放置導出

foo.hpp

class EXPORT_ME foo2();

void EXPORT_ME foo_funct(foo2 *foo_ptr);

並且任何需要使用導出項的文件只需要調用foo.hpp頭中定義的方法(默認行為是導入)

use_foo.cpp

main()
{
      #include "foo.cpp";
foo2 myfoo;
foo_funct(&my_foo);
}
  • 正如其他人所說,lib是靜態鏈接的,而dll是動態鏈接的。 靜態鏈接時,任何引用的元素都會在編譯時串聯放入源中,並且通常會產生更大的程序(就文件大小而言),而動態鏈接的元素在運行時鏈接,因此文件大小通常較小。 靜態與動態還有許多其他優點/缺點 - 我建議您按照Doc Browns鏈接獲取更多信息

切換到MinGW下的gcc。 構建和鏈接到DLL就像構建和鏈接到靜態庫一樣簡單。 它甚至透明地處理C ++名稱修改(但是調用程序也需要用gcc編譯)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM