2016-11-18 110 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

相关问题