2014-01-29 66 views
4

我已經繼承了一個C++項目,並且需要將它轉換爲DLL,才能在其他項目中使用它。如何使用Visual Studio 2010中的DEF文件從現有的C++代碼生成DLL

該代碼是在Visual Studio 2010解決方案中構建的。我能夠編譯它並生成一個DLL文件,但沒有關聯的lib文件。我不是一個Windows 8開發者,但目前看來,我需要出口,我想使用的功能,有兩種方式:

第一個選擇意味着在我想導出的每個類或函數前面手動添加__declspec(ddlexport)。由於有很多類,而且我沒有控制所有將與庫鏈接的應用程序,所以第二個選項(DEF文件)看起來更有希望。

有沒有什麼辦法從現有的DLL文件生成一個DEF文件?我試過不同的解決方案:

  • 使用expdef。它只是在沒有任何信息的情況下崩潰。
  • 使用dumpbin。我沒有看到函數名稱。就在:

    文件類型:DLL

    摘要

    1000 .data 
        2000 .idata 
        18000 .rdata 
        5000 .reloc 
        1000 .rsrc 
        98000 .text 
        48000 .textbss 
    

罷了。我想這意味着我不會輸出任何東西。但是,這正是我想要做的。我該怎麼做?

+0

也許這可以幫助你: http://stackoverflow.com/questions/ 14402415/export-function-from-dll-in-visual-studio-2010-using-def – Matz

+4

第一份工作是避免導出* everything *。一個DLL的公共接口需要被設計*,這不是一種將屬性代碼化的隨機行爲。如果您確實需要導出C++類,請注意這樣做的相當大的危險,那麼您非常希望使用__declspec(dllexport)。用DEF文件做這件事是殘忍和不尋常的懲罰,一定會出錯。 –

+0

對不起,我的啞巴級問題。當我聲明一個類時,我有一些公共屬性和方法。到現在爲止還挺好。現在,假設我們有100個課程。每個班級都有自己的公共屬性和成員。在我的(可能是天真的)方法中,我只想將代碼打包到一個庫(一個DLL文件)中,讓其他程序只調用每個類的公共接口。所以,如果我使用「public」來定義這個接口,爲什麼我需要另一種機制來說明哪些部分必須被視爲公共的並且被暴露以被調用? – jorgeas80

回答

1

經過幾年的反覆碰到這個問題,我今天找到了一個解決方案。這有點冒險,但它實際上可能是Visual Studio最好的方式。

由於您不想導出每個可能的符號(特別是因爲您的DLL本身可能包含大型靜態庫),並且您不能編輯帶有符號的文件(對於我來說,這是因爲它們'需要靜態鏈接以遵循其使用模式的第三方庫),DEF是最佳解決方案。

如果我們有:

  • 應用程序(EXE)
  • 庫(DLL)
  • 圖書館有DEF文件,這意味着當你構建,在.DEF上市符號將出口Library .DLL並在.LIB文件中列出。
  • DEF文件是空
  • 應用鏈接庫的庫文件

現在生成!

OK,我們得到了很多的鏈接錯誤的... Linker errors

現在到「輸出」選項卡,並注意輸出的文本中在每個連接器末端的符號名錯誤行:

Linker error text

我們可以創建一個小腳本需要每一行的最後一個「字」,起飛括號,然後把在您的DEF文件。它的工作原理!

就像我說的那樣有點不好意思(因爲當時你只能得到應用程序使用的符號)。但實際上,因爲您不想導出所有內容,並且您可能需要該庫靜態鏈接的庫中的符號,所以它可能是最準確的方法。

(注:對我來說,它主要是試圖讓插件DLL可以訪問應用程序中的EXE符號問題)

2

爲什麼不指定在您的項目中創建一個implib並重新編譯。 Here是相關信息。 這將導出所有內容,並且您的其他項目可以鏈接到implib(.lib文件)以使用此dll。另一方面,如果您希望避免導出DLL中的所有內容,那麼您需要創建一個API(最好是C,以便與非Microsoft編譯器兼容,如果甚至是這種情況),然後僅導出這些函數。這可以通過創建一個小文本文件,將其重命名爲.def並將其添加到項目中來完成。此文件的格式詳細記錄在MSDN,但你需要的最低限度是這樣的:

LIBRARY MyDLLName 
EXPORTS 
    function1 
    function2 
    .... 

以上將需要使用的代碼功能的確切名稱。這些函數應該聲明爲外部「C」以避免C++名稱變形,並且WINAPI指定32位代碼的調用約定。 但是導出的名稱可以是更多的「可讀性」如果你把它寫這樣的:

LIBRARY MyDLLName 
EXPORTS 
    exportedName1=internalFunctionName1 
    exportedName2=internalfunctionName2 
    .... 

有關語法的詳細信息請參見here

+0

我最近添加了一個項目並進行了編譯。但現在。當我嘗試使用DEF文件時,它總是說LINK:致命錯誤LNK1104:無法打開文件'/DEF:C:\d.def .. – Ragav

+0

此錯誤意味着「無法打開文件名」 - 將您的.def文件放在其餘位置的來源是,並將其添加到項目中。然後在設置中指定要使用.def文件。錯誤中報告的文件名有點奇怪。似乎你試圖將它添加到命令行上? – DNT

相關問題