2014-05-02 67 views
0

這裏是一個益智遊戲,我找不到答案(在這裏SO或其他網站)。我是一個新手,但我試圖快速學習。MS VS 2010入口點程序不能在更改後找到過程名稱

我需要我的DLL入口點過程的名稱從

int subCreatePipe() 

改變

int subCreateNewPipe() 

但是,當我這樣做,啓動程序死掉。

特定的錯誤是:

「過程入口點subCreateNewPipe不能設在動態鏈接庫myPipe.dll」

我上運行的設置是:

  • Windows 7
  • MS Visual Studio 2010
  • C++的Win32
  • 未受管(沒有CLI)
  • MBCS

    • 我創建了一個 「myPipe.dll」(使用上述的設置)來測試我創建一個DLL和打開一個管道的能力。
    • 我創建了一個「TestPipe.cpp」(使用上面的設置,但與Win32控制檯),所以我可以運行一個程序,將鏈接到DLL並顯示一些結果給我。
    • (我也有其他的程序,將送東西給管。)

現在,這裏的踢球者:

  1. 我創建了一個它稱之爲int subCreatePipe()程序的DLL。
  2. 我編譯成功。
  3. 我將發佈文件移動到我的TestPipe項目「Lib」子文件夾中。
  4. 在TestPipe.cpp我有一個行調用的程序:

    x = subCreatePipe(); 
    
  5. 我編譯TestPipe.cpp並運行發佈的「TestPipe.exe」,它運行完美。 它找到subCreatePipe的入口點。

但我需要的DLL程序重命名爲subCreateNewPipe堅持命名約定,我沒有控制權。

  1. 我myPipe.dll程序重命名爲int subCreateNewPipe()
  2. 我成功編譯它。
  3. 我將發佈文件移到我的TestPipe項目「Lib」子文件夾中。 (刪除舊文件)
  4. 在TestPipe.cpp我改變調用的程序:

    x = subCreateNewPipe(); 
    
  5. 我編譯TestPipe.cpp並運行發佈的「TestPipe.exe」和它死(與上面給出的錯誤)。

如果我回去並將DLL過程名稱更改爲subCreatePipe,它將再次運行。如果我回去並將其更改爲subCreateNewPipe,它會再次死亡。我所做的唯一不同的是改變入口點過程名稱。

所以我的問題是:

  1. 有沒有辦法在VS 2010中重新命名一個入口點過程?
  2. 即使我將它留空,我是否應該使用DLLMain()? (這看起來很糟糕)
  3. 有一些隱藏的開關我失蹤了嗎?
  4. Linker真的在做什麼?
  5. 是否有名稱正在繼續?
  6. 還是在第一次編譯項目後還有別的東西無法更改?

一些其他的東西我想(仍然給出了相同的結果「的第一種方式工作」,而是「第二種方式失敗」):

  • 我嘗試使用__stdcall

    int __stdcall subCreatePipe() // works 
    int __stdcall subCreateNewPipe() // doesn't work 
    
  • 我嘗試使用__declspec(dllexport)

    ifdef X_EXPORT_FLAG 
    #define DLL_IMPORT_EXPORT __declspec(dllexport) 
    else 
    #define DLL_IMPORT_EXPORT __declspec(dllimport) 
    endif 
    
    X_EXPORT_FLAG int __stdcall subCreatePipe() // works 
    X_EXPORT_FLAG int __stdcall subCreateNewPipe() // doesn't work 
    
  • 我也嘗試使用.DEF文件來定義鏈接器的過程名稱。

    int subCreatePipe() // works 
    int subCreateNewPipe() // doesn't work 
    

(在所有的例子我改變TestPipe.cpp代碼來調用適當的程序名稱。)

如果你看不出來,我對試圖找出有點強迫症走出去,讓這個工作。

我現在要去創建一個新的Win32控制檯應用程序來調用DLL(我應該在24小時前完成的)。但是,我仍然很好奇爲什麼我無法更改入口點過程名稱。對於爲什麼無法完成,更好的編碼技術,或者如何解決這個鏈接器問題的任何見解都會受到歡迎。

+0

如果我理解你的問題,你不應該使用術語「dll入口點過程」。 DLL入口點是加載程序在加載DLL時調用的,並且是一種相當先進的設置,很少需要與之混淆。你似乎在談論的是從應用程序調用的DLL導出。 –

+0

這聽起來像應用程序正在查找一箇舊的DLL版本。確保更新的DLL位於應用程序將從中加載它的位置。 –

+0

嗨邁克爾:)感謝您的回覆。我得到的錯誤信息是「... procedure Entry Point ...」,所以這就是我在描述中使用它的原因。我沒有觸及dll入口點的Configuration-> Linker-> Advanced選項。該設置保持空白。另外...我同意這聽起來像一箇舊的DLL可能是問題。但事實並非如此。我每次清除我的dll libray文件夾並複製到新的dll Release文件中。當我編譯原始程序名稱時...它起作用。當我嘗試更改原始程序名稱時,它不起作用。 ......我知道......它也讓我感到困惑。 – abraxascarab

回答

0

SOLUTION:

非託管 C++,DLL的沒有得到清理的 「釋放」 文件夾,他們託管C做的方式++。每次更改DLL時,都必須將新DLL移動到應用程序的「發佈」文件夾中。

我學會了如何對付更新DLL在託管 C++,所有你需要做的(在你的應用程序文件夾)是清除掉舊的DLL庫的子文件夾,並在變化後的DLL的新版本複製到該空的庫子文件夾中。當您「清理並重新構建」調用這些DLL的應用程序時,VS2010 C++會將舊DLL從「發佈」文件夾中刪除,並將新DLL從庫子文件夾複製到應用程序「發佈」文件夾中。它很好地保持你的DLL是最新的。

非託管 C++,「清潔和重建」不刪除舊的DLL了應用程序的「釋放」文件夾中。它從您的庫子文件夾複製新的DLL的。所以,即使我認爲我將我的新DLL放在一個我的程序可以找到它們的文件夾中,但它們並未像Managed C++一樣被複制。

當Michael Burr給我link /dump /exports myPipe.dll工具時,我能夠看到DLL的時間戳和可用的過程。 (在我的情況下,它是第一個只有一個過程的DLL構建。)很明顯這是一箇舊的DLL,而不是當前的DLL。

這解釋了爲什麼應用程序始終使用舊的過程名稱運行。但是,使用新過程名稱進行編譯時,由於應用程序只能找到舊DLL(新過程名稱不存在),因此它提供了過程入口點錯誤。

再次感謝! :)