2011-09-23 71 views
3

我正在使用外部DLL來使用我寫的包裝器來使用OCR設備。我已經對包裝進行了測試,並且完美地工作。但是,當我使用WinForms項目來使用包裝程序的客戶機類(位於另一個項目中)時,調用從DLL導入的C#方法(使用[DLLImport(...)])說該DLL未註冊時出現錯誤。我需要在WinForms應用程序中使用外部DLL的哪個配置?

錯誤說:

「DLL庫函數沒有發現檢查註冊表中的安裝路徑。」

所有執行都在調試模式下完成。 我比較了兩個項目的配置。最相關的區別是Test項目面向任何CPU,而WinForms應用程序只指向x86。

什麼可能呢?

更新

  1. 我試圖註冊使用Regsvr32.exe的DLL,但沒有奏效。我想過使用Gacutil.exe但是卸載以後的.NET Framework 1.1的所有框架也需要...
  2. 我不知道......在測試環境可能一切正常,因爲測試框架有它的DLL文件或可執行文件(或類似的東西)完全註冊在Windows中,所以這些是可信的DLL。調試生成的DLL可能不被Windows信任,因此會出現此問題?
  3. 我在同一個令人不安的項目創建一個表單,然後我打電話OCRWrapper從我加入一個按鈕。 OCR的工作!不幸的是,很難重寫第一種形式,因爲我們投入了大量的時間;所以,我一直在想什麼,我需要在令人不安的形式來改變...
  4. 我再次開始從頭形式的發展和加入所有與之相關的部件;一切運行良好,OCR成功讀取所有數據。當我通過調用ObjectContext加載組合框並再次出現錯誤...我使用的是連接到Oracle的實體框架。
+0

您是否在64位系統上運行? – stuartd

+0

@StuartDunkeld英特爾核心2二重奏...我想這是一個64位系統,但是,雖然我GOOGLE了它,但我並沒有確定... – JPCF

+0

@HansPassant異常不是來自Visual Studio。 ..當我從de OCR中調用一個方法時(使用'[DLLImport]'標記的方法),返回的錯誤信息是'「找不到DLL Library函數。 – JPCF

回答

1

我有一個理論。

讓我們想象一下以下情況:

  • 的ocr.dll取決於一些其他本地DLL,讓我們把它叫做other.dll [A]
  • 你的ADO.NET提供者使用引擎蓋下機DLL(這是千真萬確的ODP.NET),這取決於other.dll [B],這恰好具有相同的名稱,但實際上是一個不同的DLL(或至少不同的版本)相比other.dll [A]

然後,在運行時,這可能會發生:

  • 當您連接到數據庫,ADO.NET提供動態地加載其本機DLL,包括other.dll [B]
  • 然後您嘗試從OCR DLL調用函數。所述的P/Invoke試圖動態加載OCR DLL和成功,但other.dll [B]已經裝載和ocr.dll試圖使用一些功能從它,而不是從other.dll [A]它實際存在的地方。

歡迎來到DLL地獄。所以,你可以做什麼?

  • 嘗試改變調用ocr.dll和ADO.NET提供程序的次序以查看任何更改。如果您(非常)幸運,other.dll [A]可能實際上是一個新版本,仍然向下兼容other.dll [B]和事情大神奇地開始工作。
  • 嘗試另一個版本的ADO.NET提供程序。
  • 嘗試另一個ADO.NET提供程序。
  • 嘗試從供應商處獲得一個靜態鏈接的ocr.dll(即沒有運行時依賴於other.dll [A])。
0

所以,在調用DLL從一個按鈕的工作原理,但它不會從一個複雜的形式工作。我會說有一個未定義的行爲正在進行。問題依然存在,無論是你,編寫錯誤的編碼,還是編寫錯誤的DLL。

因爲我們沒有訪問該DLL的源代碼,也許你可以張貼函數的原型,以及所有相關結構的定義,以及您爲它寫了的DllImport線?

+0

我不認爲錯誤是由於它的OCR失敗而造成的_only_當從特定窗體調用時...但是請看一看:[[DllImport( 「aDll.dll」)] private static extern uint aMethod()','[DllImport(「aDll.dll」,CallingConvention = CallingConvention.Cdecl,CharSet = CharSet.Ansi)] private static extern string aMethod2(ulong aParameter);' ,'[DllImport(「aDll.dll」,CallingConvention = CallingConvention.Cdecl,CharSet = CharSet.Ansi)]'',私人靜態不安全的外部超時aMethod3(參考IntPtr aParameter,ref IntPtr anotherParameter,ref IntPtr afterTheLastParameter);'。 – JPCF

+0

我正在與一個隱私的DLL的安全業務我不能透露具體的細節。但簽名像我寫的[這裏](http://stackoverflow.com/questions/7515798/problem-at-marshalling-a-standard-c-string-to-ac-string),[這裏] (http://stackoverflow.com/questions/7423376/how-can-i-write-a-signature-on-c-for-a-wrapped-c-method-having-double-indirect)和[這裏]( http://stackoverflow.com/questions/7410382/how-can-i-write-a-signature-on-c-for-a-wrapped-c-method-having-a-pointer-to-a) – JPCF

+0

什麼你所做的很棘手......我剛剛看到其他的SO問題,我不太確定它們是否完全正確。我需要看到這些函數的C原型,並且可能使用它們的一些示例C代碼。原型並不總是足夠寫一個適當的馬歇爾,你需要行爲信息。 – rodrigo

0

谷歌無法找到該錯誤消息,這意味着(不是絕對:)雖然它不是一個系統消息,但是一個自定義的來自在DLL中的代碼。所以這個DLL會做一些狡猾的事情。我想它會嘗試在你的內部調用另一個函數。

幾件事我建議你試試:

  • 運行的x86配置。在項目屬性 - > Build選項卡中將平臺設置爲x86。這是假設該DLL是一個x86 dll。

    DUMPBIN /頭orc.dll

    File Type: DLL 
        FILE HEADER VALUES 
    
           14C machine (**x86**) 
            4 number of sections 
          4CE7B6FC time date stamp Sat Nov 20 11:54:36 2010 
            0 file pointer to symbol table 
            0 number of symbols 
            E0 size of optional header 
           2102 characteristics 
             Executable 
             32 bit word machine 
             DLL 
    

此命令行應該告訴你的位數。如果它是一個64位運行一個64位配置,但我敢打賭它是32位。

  • 不要在項目中包含該dll。我想你已經這麼做了。確保dll位於%PATH%環境變量中的文件夾中。當你在命令提示符下運行以下命令:

其中ocr.dll

應該告訴你該DLL是。如果它不會將安裝dll的文件夾添加到%PATH%。

相關問題