无法从64位托管代码调用32位非托管DLL

问题描述:

大家好,

如果已经提出这个问题,我很抱歉。对不起,很长的帖子。



这是我的问题。



我有64位vb.net应用程序。

我有第三方32位非托管DLL。

我需要从64建立通信-bit托管应用程序到32位非托管DLL。

以下是我尝试过的东西:



1我创建了一个名为COM1的32位vb.net包装类库,并添加了一个调用32位非托管dll公开函数的vb.net COM类。

项目已注册COM互操作启用。

当我将32位DLL(COM1.dll)引用到我的64位应用程序并执行应用程序时,我收到以下异常:

无法加载文件或程序集'COM1.dll'...试图加载格式不正确的程序。



2.我创建了一个名为COM2的64位vb.net包装类库,并添加了一个调用32-bi的vb.net COM类t unmanaged dll。

项目启用了注册COM互操作。

当我将64位DLL(COM2.dll)引用到我的64位应用程序时并执行应用程序,我能够加载64位DLL但我收到以下异常当我调用非托管DLL中的一个函数(通过64位包装器DLL):

尝试加载格式不正确的程序。



我明白我无法直接将64位dll调用到我的64位应用程序。

我要做的是通过IPC机制调用32位dll;在这种情况下COM。

但是,显然,我在这里犯了一些错误。



我尝试使用WCF应用程序执行上述步骤以及我用WCF服务替换COM包装器的地方。

但是我得到了相同的结果。



有人可以给我一个工作代码或者告诉我在上述步骤中我做错了什么?



感谢您阅读并给予您时间。

真的很感激你的帮助。



问候。



我的尝试:


'我的COM类



< comclass(comclass1.classid,comclass1.interfaceid,= comclass1.eventsid)= &GT; _ $ / $
Public Class ComClass1

Public Declare Sub InitializePort LibI2CDrvrs(ByVal I2cAddr As Byte,ByVal evalBoardUsed By Byte)

#Region COM GUID

'这些GUID为此类提供COM标识

'及其COM接口。如果你更改它们,现有的

'客户将无法再访问该类。

Public Const ClassId As String =bd248311-07ca-4d09-a5d1-d4c6b4df0256

Public Const InterfaceId As String =f8de730a-d845-44c3-b029-fc556d2e7f0c

Public Const EventsId As String =abaf2635-6f30-46f7-a7a9-5a44bef46f9b

#End Region



'一个可创建的COM类必须有一个Public Sub New()

'没有参数,否则,该类将不会在COM注册表中注册,并且无法通过CreateObject创建

'。

公开Sub New()

MyBase.New()

End Sub

End Class



'我的64位应用程序

公共函数foo()作为布尔值

尝试

COM1.ComClass1.InitializePort(2,2 )

Catch ex As Exception

MsgBox(ex.ToString)

结束尝试



返回True

结束函数

Hello all,
I am sorry if this question has already been asked. And sorry for the long post.

Here is my problem.

I have a 64-bit vb.net application.
I have a 3rd party 32-bit unmanaged DLL.
I need to establish communication from the 64-bit managed application to the 32-bit unmanaged dll.
Here are the things I've tried:

1. I created a 32-bit vb.net wrapper class library, called COM1, and added a vb.net COM class that calls the 32-bit unmanaged dll's exposed functions.
The project had "Register for COM interop" enabled.
When I referenced the 32-bit DLL (COM1.dll) to my 64-bit application and executed the application, I received the following exception:
"Could not load file or assembly 'COM1.dll'...An attempt was made to load a program with an incorrect format."

2. I created a 64-bit vb.net wrapper class library, called COM2, and added a vb.net COM class that calls the 32-bit unmanaged dll.
The project had "Register for COM interop" enabled.
When I referenced the 64-bit DLL (COM2.dll)to my 64-bit application and executed the application, I was able to load the 64-bit dll but I received the following exception when i called one of the functions exposed in the unmanaged dll (via the 64-bit wrapper dll):
"An attempt was made to load a program with an incorrect format."

I understand that i cannot call a 32-bit dll directly to my 64-bit application.
What I am trying to do is call the 32-bit dll through IPC mechanism; in this case COM.
But, obviously, I am making some mistake here.

I tried the above steps using a WCF application as well where i replace the COM wrapper with the WCF service.
But I get the same result.

Can someone give me a working code or tell me what am I doing incorrect in the above-mentioned steps?

Thank you for reading and giving your time.
Really appreciate your help.

Regards.

What I have tried:

'My COM class

<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 = "bd248311-07ca-4d09-a5d1-d4c6b4df0256"
Public Const InterfaceId As String = "f8de730a-d845-44c3-b029-fc556d2e7f0c"
Public Const EventsId As String = "abaf2635-6f30-46f7-a7a9-5a44bef46f9b"
#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

'My 64-bit application
Public Function foo() As Boolean
Try
COM1.ComClass1.InitializePort(2, 2)
Catch ex As Exception
MsgBox(ex.ToString)
End Try

Return True
End Function

我找到了对我的问题一个相当简单的解决方案我使用Socket Class的方法和属性实现了一个客户端 - 服务器模型。我启动一个32位托管服务代码作为服务器。服务器调用32位非托管dll的功能。因此,在某种程度上,服务器充当非托管dll的包装器。我使用我的64位应用程序作为客户端。我从客户端传递一个字符串到服务器。该字符串包含有关要调用的函数及其参数的信息。我解析服务器中的字符串并调用非托管DLL中的相应函数。
I have found a rather simple solution to my problem. I implemented a client-server model using Socket Class' methods and properties. I start a 32-bit managed-service code working as the server. The server calls the functions of 32-bit unmanaged dll. So in a way the server acts as a wrapper for the unmanaged dll. I use my 64-bit application as client. I pass a string to the server from my client. The string contains information on the function to be called and its arguments. I parse the string in server and call the appropriate function in the unmanaged dll.