2016-11-18 106 views
2

我有一個64位VB.Net應用程序需要使用第三方32位非託管DLL。無法從64位託管代碼調用32位非託管DLL

這裏是我試過的東西:

  1. 我創建了一個32位vb.net包裝類庫,稱爲COM1,並補充說,調用32位的一個VB.Net COM類非託管dll的暴露功能。 該項目啓用了「註冊COM互操作」。 當我所引用的32位DLL(COM1.dll)到我的64位應用程序並執行該應用程序,我已收到以下情況例外:

    無法加載文件或程序集「COM1.dll」 ..試圖加載格式不正確的程序。

  2. 我創建了一個64位vb.net包裝類庫,稱爲COM2,並補充調用32位非託管的DLL一個VB.Net COM類。 該項目啓用了「註冊COM互操作」。 當我在64位應用程序中引用64位DLL(COM2.dll)並執行應用程序時,我能夠加載64位dll,但當我調用其中一個公開的函數時,我收到以下異常非託管的DLL(通過64位包裝DLL):

    試圖加載程序格式不正確。

  3. 我嘗試了上述步驟使用WCF應用程序以及我用WCF服務替換COM包裝,但我得到了相同的結果。

我知道我無法直接從我的64位應用程序調用32位dll。我想要做的是通過IPC機制—調用32位DLL,在這種情況下COM或WCF。顯然,我在這裏犯了一些錯誤。

有人可以給我一個工作代碼或告訴我在上述步驟中我做了什麼不正確?我的代碼


部分:

  1. 我的COM類

    <ComClass(ComClass1.ClassId, ComClass1.InterfaceId, ComClass1.EventsId)> _ 
    Public Class ComClass1 
        Public Declare Sub InitializePort Lib "I2CDrvrs" (ByVal I2cAddr As Byte, ByVal evalBoardUsed As Byte) 
    
    #Region "COM GUIDs" 
        ' These GUIDs provide the COM identity for this class 
        ' and its COM interfaces. If you change them, existing 
        ' clients will no longer be able to access the class. 
        Public Const ClassId As String = "5da6d3a4-848c-42b1-bc7c-4079ec5457b1" 
        Public Const InterfaceId As String = "8de9508b-fda6-496e-bb29-a90dc5282d2c" 
        Public Const EventsId As String = "cfec40ff-fec0-4250-9d72-9d63f1e37d21" 
    #End Region 
    
        ' A creatable COM class must have a Public Sub New() 
        ' with no parameters, otherwise, the class will not be 
        ' registered in the COM registry and cannot be created 
        ' via CreateObject. 
        Public Sub New() 
         MyBase.New() 
        End Sub 
    End Class 
    
  2. 我的64位應用程序

    Public Function foo() As Boolean 
        Try 
         COM1.ComClass1.InitializePort(2, 2) 
        Catch ex As Exception 
         MsgBox(ex.ToString) 
        End Try 
        Return True 
    End Function 
    

回答

0

我發現了一個相當簡單的解決方案來解決我的問題。 我使用Socket類的方法和屬性實現了一個客戶端 - 服務器模型。 我開始一個32位託管服務代碼作爲服務器。服務器調用32位非託管dll的功能。所以在某種程度上,服務器充當了非託管dll的包裝。 我使用我的64位應用程序作爲客戶端。 我從我的客戶端傳遞一個字符串到服務器。 該字符串包含有關要調用的函數及其參數的信息。 我解析服務器中的字符串並調用非託管dll中的相應功能。

0

將COM DLL引入爲中介(無論是32位還是64位)並不能解決問題。您仍然試圖將該32位庫加載到64位進程中。沒有任何COM技巧會解決這個問題。

32位庫必須從32位進程內運行,並通過[插入您的進程間方法選項]與您的64位程序進行通信。

您可以使用COM作爲中介,當然;這不是一個壞主意。但是,該COM中介必須是一個進程外服務器(一個EXE),而不是一個DLL。

快速完成此操作的方法是將COM助手安裝爲COM +(組件服務)應用程序。編譯爲「32位」,而不是「AnyCPU」。確保它作爲「服務器」安裝,而不是「庫」。 COM +將爲其提供32位主機進程。

無論您是否可以負擔運行意圖通過進程外主機在進程中運行的庫的開銷,我都不知道。這將取決於圖書館的工作。在某些情況下,它可能根本不可能(例如,在過程仿射資源上運行的庫)。

如果DLL必須在程序中運行,那麼您只有兩個選擇:a)您的程序必須編譯爲32位。或者,b)您必須購買64位版本的庫。

+0

感謝您的回答。我能夠創建一個COM +服務器。我將我的32位.NET包裝器導入到組件服務中,並在「正在運行的進程」窗格中看到我的服務(作爲服務器安裝)。但我不確定如何將其引用到我的64位應用程序。 – user7176709

+0

您可以像以前一樣引用它。 COM處理差異。 –

+0

我添加了32位dll作爲參考。但我仍然得到「BadImageFormat異常」。看來我試圖通過我的應用程序以某種方式直接調用dll。我需要設置COM服務的任何屬性嗎? – user7176709

相關問題