簡體   English   中英

無法從64位托管代碼調用32位非托管DLL

[英]Unable to call 32-bit unmanaged DLL from 64-bit managed code

我有一個64位VB.Net應用程序,該應用程序需要使用一個第三方32位非托管DLL。

這是我嘗試過的事情:

  1. 我創建了一個名為COM1的32位vb.net包裝器類庫,並添加了一個VB.Net COM類,該類調用了32位非托管dll的公開函數。 該項目啟用了“注冊COM互操作”。 當我將32位DLL(COM1.dll)引用到我的64位應用程序並執行該應用程序時,我收到以下異常:

    無法加載文件或程序集“ COM1.dll” ...試圖加載格式錯誤的程序。

  2. 我創建了一個名為COM2的64位vb.net包裝器類庫,並添加了一個VB.Net COM類,該類調用了32位非托管dll。 該項目啟用了“注冊COM互操作”。 當我在64位應用程序中引用64位DLL(COM2.dll)並執行該應用程序時,我能夠加載64位dll,但是當我調用以下代碼中公開的功能之一時收到以下異常:非托管dll(通過64位包裝器dll):

    試圖加載格式錯誤的程序。

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

我知道我不能直接從我的64位應用程序調用32位dll。 我想做的是通過IPC機制(在這種情況下為COM或WCF)調用32位dll。 顯然,我在這里犯了一些錯誤。

有人可以給我一個工作代碼或告訴我我在上述步驟中做錯了什么嗎?


我的部分代碼:

  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 

引入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位版本。

我已經找到了解決我的問題的簡單方法。 我使用套接字類的方法和屬性實現了客戶端-服務器模型。 我啟動一個32位托管服務代碼作為服務器。 服務器調用32位非托管dll的功能。 因此,在某種程度上,服務器充當了非托管dll的包裝器。 我將64位應用程序用作客戶端。 我從客戶端將字符串傳遞給服務器。 該字符串包含有關要調用的函數及其參數的信息。 我解析服務器中的字符串,並在非托管dll中調用適當的函數。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM