3

I have a 32 bit in-proc STA VB6 dll. I sadly cannot do anything about this. My C# component greatly benefits from being 64 bit. Is there anyway to call/interface with this 32-bit dll from my 64 bit process? Any sort of wrapper or anything?

GEOCHET
  • 21,119
  • 15
  • 74
  • 98
Steve
  • 11,763
  • 15
  • 70
  • 103
  • Possible duplicate of [Access x86 COM from x64 .NET](https://stackoverflow.com/questions/359331/access-x86-com-from-x64-net) – StayOnTarget Jun 25 '18 at 12:57

4 Answers4

11

There's no direct way you can do this.

Since you can't port the VB6 inproc dll I'd suggest you write a 32bit out of process server that implements the same interfaces and have it delegate down to the VB6 code. Then, your 64bit app can call the out of process server as COM will take care of marshaling the types between the processes.

It ain't pretty, bit it will work!

Sean
  • 60,939
  • 11
  • 97
  • 136
  • Yes there is a way to do this, see my answer for detailed instructions. – Ben Mar 28 '13 at 09:48
  • Doing it out of process may be an option but the statement that it can't be done seems to be incorrect. – StayOnTarget May 22 '18 at 17:04
  • @DaveInCaz _ I don't say it can't be done, I say there's no direct way to do it - there's a difference. You can't load the 32bit DLL into a 64bit process, but you can load it into a 32bit process and access it as an out-of-process server. – Sean May 22 '18 at 18:11
  • Fair point though I guess I think of com as being rather indirect all the time so the extra layer of the surrogate process didn't seem like a big conceptual difference to me. – StayOnTarget May 22 '18 at 23:05
7

This article Dealing with Legacy 32-bit Components in 64-bit Windows help you :

I have found this solution, see in article :
• Converting a project type from in-process to out-of-process
• Using COM+ as a host (this work for me)
• Using dllhost as a surrogate host

Glorfindel
  • 21,988
  • 13
  • 81
  • 109
lsalamon
  • 7,998
  • 6
  • 50
  • 63
  • The dllhost surrogate seems like the most direct approach by far. The other answer to this question has a much more detailed explanation. https://stackoverflow.com/a/8908105/3195477 – StayOnTarget May 22 '18 at 17:03
5

You can load a (for example) 32-bit only DLL in a surrogate, and access it from a 64-bit process, in the following manner.

This will work provided there is a marshaller available, which there generally will be for a component with a typelib because they usually use the standard marshaller. It will not work if the object requries a custom prox/stub because 64 bit versions won't exist, or you wouldn't have this problem in the first place.

How to register a third-party 32-bit component for use from a 64-bit client

First you need an AppID. If the DLL already has an AppID, you should use that. You can find out by checking under the CLSID key for the CoClass you are interested in.

The example used here is the Capicom.HashedData and Capicom.EncryptedData classes. Capicom is 32-bit only.

  • AppID: CAPICOM does not have an AppID, so for the AppID I have just used the CLSID of the EncryptedData class.

  • CLSID: You need a list of the CLSID of each class you want to be able to create from 64-bit clients. In this example, it is just EncryptedData and HashedData.

  • Registration: Create a registry file containing the details, as per the example, and load it into the registry.

You should use the 32-bit version of Regedit to do this, as it is a 32-bit component. If you have a 64-bit component you want to access from 32-bits, use the other one. (This is because of the registry virtualisation for the 32-bit compatibility layer- using the the matching bitness version of regedit takes care of this issue for you, by making sure you edit the correct virtualised version of the registry).

Windows Registry Editor Version 5.00


;;; Capicom AppID - just using the Capicom.EncryptedData CLSID
;;; Use default surrogate = empty string
[HKEY_CLASSES_ROOT\AppID\{A440BD76-CFE1-4D46-AB1F-15F238437A3D}]
"DllSurrogate"=""

;;; Capicom.EncryptedData
[HKEY_CLASSES_ROOT\CLSID\{A440BD76-CFE1-4D46-AB1F-15F238437A3D}]
AppID="{A440BD76-CFE1-4D46-AB1F-15F238437A3D}"

;;; Capicom.HashedData - use same AppID for all!!!!!
[HKEY_CLASSES_ROOT\CLSID\{CE32ABF6-475D-41F6-BF82-D27F03E3D38B}]
AppID="{A440BD76-CFE1-4D46-AB1F-15F238437A3D}"

Save to a myComponent-dllhost.reg file, and away you go.

c:\windows\sysWow64\regedit.exe "myComponent-dllhost.reg"

You should now be able to access Capicom.HashedData and Capicom.EncryptedData from 64-bit script/COM hosts.

Notes:

  • This only works for basic OLE Automation types. Any object compatible with Windows Scripting Host scripts in VBScript or JavaScript should be OK.
  • You only have to add the AppID to directly creatable objects. That's basically those with an InprocServer32 entry. Objects which are generated from factories or which are only available as child objects do not have to have an AppID added.
  • If there is already an AppID all you need to do is add the empty-string "DllSurrogate" entry. That's it!
  • this will NOT affect normal clients of the DLL. As long as the bit-ness matches, they will continue to be loaded in-process as before. The only difference it will make is that it will become possible to instantiate it out-of-process from a client of a different bitness.
Ben
  • 34,935
  • 6
  • 74
  • 113
3

The 32bit COM component will have to run out of process.

Before embarking on creating a wrapper, check out whether COM+ (Object Services) will host it.

Richard
  • 106,783
  • 21
  • 203
  • 265
  • Hosting in COM+ as a server application I think would work. Course depends on the dll but great idea. – JoshBerke Mar 04 '09 at 17:46
  • Hi Richard, I'm very unfamiliar with COM+. Could you expand on your answer a bit (or direct me to resources on how to do this)? Thank you for the help. – Steve Mar 04 '09 at 18:50
  • My COM+ skills are out of date, it has been a few years since I had to seriously work with COM+. Ensuring you initialise DCOM security is a must, after that follow MSDN. – Richard Mar 04 '09 at 19:09