Reputation: 192
I have a 64-bit VB.Net application which needs to use a 3rd party 32-bit unmanaged DLL.
Here are the things I've tried:
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.
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) in 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 from my 64-bit application. What I am trying to do is call the 32-bit dll through the IPC mechanism — in this case COM or WCF. Obviously, I am making some mistake here.
Can someone give me a working code or tell me what am I doing incorrect in the above-mentioned steps?
Part of my code:
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 = "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
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
Upvotes: 2
Views: 1583
Reputation: 192
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.
Upvotes: 0
Reputation: 34018
Bringing in a COM DLL as an intermediary (be it 32-bit or 64-bit) doesn't solve the problem. You are still trying to load that 32-bit library into your 64-bit process. No amount of COM trickery will fix that.
The 32-bit library must run from inside a 32-bit process, and communicate with your 64-bit program via [insert your inter-process method of choice here].
You can use COM as an intermediary, sure; that's not a bad idea. But that COM intermediary must be an out-of-process server (an EXE), not a DLL.
A quick way to accomplish that is to install your COM helper as a COM+ (Component Services) application. Compile it as "32-bit", not "AnyCPU". Make sure it's installed as a "Server" not as a "Library". COM+ will provide a 32-bit host process for it.
Whether you can afford the overhead of running a library that was intended to be run in-process through an out-of-process host, I don't know. It will depend on what the library does. In some case, it might simply be impossible (e.g libraries that operate on process-affine resources).
If the DLL must run in-process within your program, then you only have two choices: a) Your program will have to compiled as 32-bit. Or, b) you have to procure a 64-bit version of the library.
Upvotes: 1