我想將一個非託管C++ DLL從一個嵌入式設備移植到另一個,並且面臨一些我認爲必須與內存管理和/或編譯器有關的奇怪問題。我沒有發佈太多的代碼,而是描述了我所嘗試的,因爲我已經嘗試了太多不同的事情來發布所有代碼,我認爲問題必須在更深的地方。將嵌入式DLL從eVC移植到VS2008導致沒有發現DLL
第一個設備運行WinCE 5.0並使用嵌入式Visual C++ 4.0進行編譯。第二臺設備運行的是Windows Embedded Compact 7(爲簡單起見,我將其稱爲WinCE 7),並使用VS2008進行編譯。這兩款設備都有自己的爲電路板設計的SDK。
在第一臺設備上Dll運行沒有任何問題,但在第二臺設備上使用新的SDK編譯的DLL不起作用。我tryed的PInvoke訪問DLL中的第二設備上,但在調試模式下的PInvoke線有一個C#applikation得到了錯誤信息:
Can't find PInvoke DLL NAME.dll
After some research我learnd這個錯誤可以有differend原因:
- 缺少您調用的本機庫的依賴關係。
- 天然assmebly被編譯爲錯誤的子系統(即桌面,不CE)
- 天然組件被編譯爲錯誤的處理器(即x86和不ARM)
- 沒有足夠的虛擬存儲器爲DLL加載。
我用peinfo來檢查dll。所有依賴關係都在設備上找到,它是爲WinCE 7編譯的,處理器類型是正確的。 (如果沒有,我會很驚訝,使用正確的SDK)所以仍然有4號:沒有足夠的虛擬內存。但是WinCE5僅限於32MB虛擬內存,而WinCE7可以擁有高達2GB的容量。 所以我開始嘗試一些事情來縮小錯誤,並告訴你我的結果。
首先,我把我的dll編譯爲第一個設備,並嘗試在第二個設備上使用它。令人驚訝的是.net應用程序可以找到和PInvoke這一個。但是Dll裏面的一些函數似乎沒有正確運行,所以我想我必須使用正確的SDK。但具有正確的代碼,我知道這兩個DLL的出口必須是正確的。我知道兩個編譯器使用不同的C++名稱改變樣式,所以這也不是問題。
接下來,我在VS2008上編寫了一個簡單的C++應用程序,使用新的SDK從那裏加載DLL。在第一個設備中的應用程序運行這種方式,但現在我在第二設備上運行的遠程顯示我收到錯誤消息:
Unable to import library NAME.dll ! Program will exit.
至少現在我知道它有沒有關係.net和PInvoke的。但進一步我使用VS2008做了一個簡單的新DLL,新的SDK和ne .net應用程序能夠PInvoke它。所以在代碼中必須有一些不喜歡被加載的東西。 : -/
經過幾個小時的代碼搜索後,我意識到系統不喜歡一些全局變量。我知道全局變量很糟糕,如果他們不在那裏,我會很高興,但是我還沒有開始編寫代碼,多年以來,他們越來越多地處理它,所以他們將很難清除現在。
這些全局變量是類的實例。其中一些似乎很糟糕,其他一些似乎沒有問題。令人困惑的是,他們都是類的實例,我不知道爲什麼有好的和壞的。當我註釋掉壞的全局變量時,應用程序能夠調用Dll。其中一個不好的全局變量足以使應用程序找不到Dll。
爲什麼這樣使用VS2008與WinCE 7但不使用WinCE 5使用eVC4.0?全局變量有什麼問題?我怎麼解決這個問題?至多相同的代碼應該適用於兩個編譯器,但首先我需要一些想法,第二個編譯器有什麼問題。
你能弄清楚(至少在工作系統上)內存佔用量究竟有多大,如果其中一些被浪費了?您是否可以通過實驗切出部件,直到其工作,從而發現哪一部分是問題?你能以某種方式在那裏得到一個調試器並跟蹤加載過程來確定故障點嗎? –
在工作的WinCE 5系統上,大約有32MB的虛擬內存使用了20MB。我試過切割零件,並以這種方式來到全局。他們中的一些人似乎導致了這個問題,但剝奪了實例化爲全局的類沒有清除原因。 剩下的不多,只有幾個 – Fabian
剩下的不多,只剩下幾個基本的成員變量。當其中一些beeing切出它的作品... 在某些點上,我可以添加一個整數成員變量,使其工作,但它沒有工作沒有整數...所以這是非常令我困惑。 – Fabian