Skip to content

Accessing 32-bit DLLs from 64-bit code

30 Jun 2007

Migrating your 32-bit Windows application to a 64-bit machine can be problematic if you have 32-bit DLLs that you cannot re-write. Mike Becker shows you how you can access 32-bit DLLs from 64-bit code using built-in IPC mechanisms.

Originally published on DNJ Online, June 2007

Microsoft’s 64-bit technology first appeared with Windows Server 2003 for Itanium 2 (also known as IA64 Architecture) and for eXtended technology CPUs (also known as x64 Architecture). It offers many advantages but also raises new issues for the software developer. For example, you may still need to access existing 32-bit DLLs from a 64-bit process.

A key advantage of 64-bit technology is its ability to address up to 8Tb of memory, against a maximum of 2Gb for 32-bit processes. As a result, 64-bit technology allows most data processing to take place in memory, without any need for temporary disk storage. This can considerably increase performance and open up new data processing scenarios. There are therefore good arguments for migrating current 32-bit software products to a 64-bit platform.

Many C or C++ applications are easy to migrated to a 64-bit platform, particularly if they are written in a monolithic fashion. Sometimes they just need to be rebuilt with an x64/IA64 compiler to run as native 64-bit applications. However distributed or module-based software can cause more problems.

The conflict: 64-bit versus 32-bit

A major migration issue concerns 32-bit software components which cannot be migrated, perhaps because the source code is lost or one of the dependencies cannot be migrated.

Your 32-bit software is still supported on a 64-bit platform as 32-bit processes can be executed inside the dedicated Windows on Windows’ (WOW64) subsystem which is part of all 64-bit Windows operating systems. However a 64-bit process cannot load a 32-bit module into its process space, and a 32-bit processes cannot load a 64-bit module into its process space. The only way that communication can happen between 32-bit and 64-bit modules is through interprocess communication (IPC). In other words, 32-bit and 64-bit processes can exchange data using IPC techniques such as out-of-process COM, sockets, Windows messages or memory mapped files.

A 32-bit software product contains the main module WeatherReport which calls into the DLL WeatherStationControl. As long as both the main module and the DLL are 32-bit processes the product can run on both 32-bit and 64-bit platforms (inside WOW64). If both the main module and the DLL are migrated to the 64-bit platform, then they can both run in a native 64-bit
process. However if only the main module is migrated to 64-bit, it will not be able to load the 32-bit DLL.

The best way to migrate such a product to a 64-bit platform is to migrate both the main module and the dependency DLL, but if the dependency DLL cannot be migrated then it cannot be loaded into the 64-bit process and the application won’t work.

The solution: a surrogate process

This issue can be solved by loading the dependency DLL into a separate 32-bit process space. The main module, running as a 64-bit process, can then access the dependency DLL across the process boundary using IPC (see MSDN reference).

A 64-bit process can access a 32-bit DLL across a process boundary if the 32-bit DLL is loaded into a separate 32-bit surrogate process space, and the application makes use of the built-in IPC mechanisms that support data exchange between 32-bit and 64-bit processes.

This solution requires additional work as the 32-bit surrogate process that loads the 32-bit DLL and exposes its API must be created. Also, some changes will be necessary on the 64-bit side as the consumer must use one of the IPC techniques instead of directly accessing the 32-bit DLL. It is worth noting that, in extreme cases, this additional work could be comparable to the work involved in developing a 64-bit version of the 32-bit DLL from scratch.

One possible way of reducing these costs is to implement a 64-bit wrapper’ DLL that exposes the same functions, parameters, types and so forth as the original 32-bit DLL. This wrapper DLL can then make IPC-based calls to the original 32-bit DLL, which has been loaded into a surrogate process.

A 64-bit wrapper DLL (WeatherStationControl64.DLL) exports the same interface as the original 32-bit DLL (WeatherStationControl.DLL), so providing the same services to the main process
(WeatherReport) without you needing to make any changes to the code of either the main process or the 32-bit DLL. This wrapper DLL delegates calls to the 32-bit DLL, which is running in a surrogate process, using IPC.

The main costs of this solution arise from implementing the surrogate process, loading the 32-bit DLL and implementing the 64-bit wrapper DLL. The actual cost depends on the IPC technique used to exchange data between the 64-bit and 32-bit processes.

COM as an IPC mechanism

One of most popular IPC techniques is DCOM (Distributed COM). Originally designed for distributed systems, DCOM is still supported on 64-bit Windows platforms, so both 32-bit and 64-bit COM modules can be built. The only limitation is that 64-bit and 32-bit modules cannot reside in the same process space, so they have to interoperate across process boundaries. This is done using out-of-process’ (OOP) COM components, in the following way:

  1. Create a 32-bit component implementing a COM object which loads and calls
    into the 32-bit DLL, and exposes the 32-bit DLL interface as a COM interface.
  2. Configure this COM components for OOP by either creating a standard COM+ OOP application (using dllhost as the surrogate process), or by implementing the COM component as a dedicated COM server process using, for example, an ATL COM
    server as hosting process or a Win32 service as a dedicated COM server.
  3. Create a 64-bit wrapper DLL which implements the same interface as the
    original 32-bit DLL, imports the COM interface of the COM object created above,
    translates current calls to the exposed interface into calls to the COM object interface, transfers the call parameters, receives return values and delegates
    them to the callers.

The 32-bit DLL (WeatherStationControl.DLL) is used by a COM object (WeatherStationWrapper) which exposes the interface of the 32-bit DLL as a COM interface. The 64-bit wrapper DLL (WeatherStationControl64.DLL) makes calls to this interface which are delegated to the original 32-bit DLL. The main process (WeatherReport) calls the interface exposed by the 64-bit wrapper DLL but is in fact served by the original 32-bit DLL.

This solution should be significantly less expensive than creating a 64-bit version of the 32-bit DLL from scratch. Microsoft’s ATL technology is supported by Visual Studio with wizards and ready-written code fragments which should also help lower migration costs by saving time and reducing the likelihood of errors.


There are, however, a number of things that you still need to keep in mind:

1. Alignment
The alignment of data in memory is different for 32-bit and 64-bit processes. This means that your more complicated custom data structures may be serialized by a 32-bit process in a way that is different to that expected by a 64-bit process, and vice versa. Microsoft Windows Platform
SDK includes documentation about the differences in memory data alignment between 32-bit and 64-bit processes.

2. Data types
In most instances, 64-bit Windows uses the same data types as the 32-bit version. The differences are mainly in pointers which are 32 bits long in 32-bit Windows and 64 bits long in 64-bit Windows. The pointer-derived data types such as HANDLE and HWND are also different between 32-bit and 64-bit versions. Windows helps you to keep a single code base for both 32-bit and 64-bit software versions by offering polymorphic data types that have a different length depending on the target platform, for example INT_PTR declares an integer with the size of a pointer’. Any variable of this type is an integer which is 32 bits long on a 32-bit platform and 64 bits long on a 64-bit platform.

3. COM initialize
You can only access a COM object from a Windows application the object has been successfully initialized. The COM API function CoInitialize()must be called for each thread that is going to access a COM object before any COM interface calls are made, and the complementary call CoUninitialize() must be performed before the thread exits (see MSDN reference). This rule must be strictly respected if the main process calls to the original 32-bit DLL are multi-threaded.

4. Security
The OOP COM component instantiates COM objects in a separate process, whether a surrogate process, a COM server or Win32 service. This can mean that calls to the 32-bit DLL may happen in a different security context to the main process, especially if the main process makes intensive use of impersonation. If this is the case you may want to configure dedicated credentials for the OOP component, or implement internal impersonation in the COM object.

5. Performance
The IPC-based solution is almost certain to be slower than making direct calls into the DLL. Data marshaling over process boundaries, automatic data conversion between 32 and 64 bits, WOW64 features and delays while instantiating the COM object will all impact performance. However
there are numerous optimizing techniques that you can use such as COM pooling, caching inside the wrapper DLL, chunky’ versus chatty’ calls over process boundaries, implementing performance critical interfaces directly in the 64-bit DLL, and so forth.

6. Redirection
The WOW64 subsystem is in charge of supporting 32-bit modules on 64-bit Windows. To avoid unwanted collisions between 32-bit and 64-bit software, particularly when accessing the file system and registry, WOW64 isolates 32-bit modules using a process called redirection’ (see MSDN reference). For example, for a 64-bit process the call to obtain the system folder pathname returns %WINDOWS%\System32, but for a 32-bit process it returns %WINDOWS%\SysWOW64. The program folder path for a 64-bit process is Program Files’, but for 32-bit process it is Program Files (x86)’. The registry key HKEY_LOCAL_MACHINE\Software contains 64-bit process settings and data, while the key HKEY_LOCAL_MACHINE\Software\WOW6432Node contains 32-bit process settings and data.

This redirection is activated automatically when software modules call to popular pre-defined system paths or registry keys.

7. Kernel modules
The solution proposed here is for 32-bit user level DLLs, and doesn’t work with 32-bit drivers. This is because 32-bit kernel modules cannot be used on a 64-bit platform, with no exceptions or workarounds. If your product includes any kernel level module, such as a device driver, then the only possible migration route is to re-write the kernel module as a 64-bit process.

8. Setup
Using a COM OOP component in place of direct calls to a DLL requires changes to your setup procedure as the COM components must be installed and registered by the system. As discussed under ‘Security’ above, this may involve configuring dedicated credentials for the COM


Best Practices for WOW64:

MSDN on Interprocess Communications:

Introduction to Developing Applications for the 64-bit Itanium-based Version of Windows:

Understanding CoInitialize():

Mike BeckerMike Becker is a senior consultant at Microsoft Consulting Services in Germany, working in the Custom Development department where he supports Microsoft customers with made-to-measure software for telecommunication. He has over 25 years programming experience, much of it involved in implementing Microsoft technologies and particularly system drivers. Mike has obtained numerous software architecture and design certifications for Microsoft and non-Microsoft technologies.

65 Comments leave one →
  1. Tobias permalink
    12 Aug 2011 09:13


    I found your article very interesting but acording to this ( registry reflection is disabled with Windows 7 so I get only “Class not registered” if I try to initiate with “CoCreateInstance” because the CLSIDs including InprocServer32-keys are not reflected anymore because Microsoft assumed that 32-bit-DLLs would not be loaded.
    Or do you have any workaround for this?

    I decided to create a COM-EXE-Server to avoid this problem.




  2. James permalink
    17 Oct 2011 20:44

    Do you still have the sample code that was provided with this article? Am trying to implement this myself and it is failing. Thanks


    • Matt Nicholson permalink*
      19 Oct 2011 13:14

      Unfortunately not. Mike Becker may have a copy, but I do not have any contact details for him. Sorry!


    • Mike permalink
      26 Sep 2013 22:44

      James, the samples were built with VS7.0/7.1 and .NET 2.0. If you still need smth -let me know, put RE: here


      • 27 Sep 2013 11:03

        Thanks for responding, Mike. Your article is still proving popular after all these years!


      • Qazi Ahmad permalink
        24 Sep 2014 16:05

        Hello Mike,
        do you have an example project for the described method in the article above ?
        Thanks in advance.


      • Mike permalink
        24 Sep 2014 16:30

        sure, ping me next week – I’m hittin the road


      • Qazi permalink
        30 Sep 2014 09:26

        Hi Mike,
        how should I contact you ?
        I am a student from Germany and need the sample project for my studies.
        Thanks in Advance.


      • Ram Mokkapati permalink
        27 Mar 2015 17:06

        Hi Mike,

        Could you please send me the source code to enable me to learn this concept quickly?

        Thanks and Regards,


      • Allwyn permalink
        15 Jul 2015 01:43

        Hi Mike,

        I know you wrote the article a while back. Curious if I could possibly get a copy of the source.

        Thanks in advance.


      • Elijah permalink
        13 Aug 2015 20:56

        Hey Mike,

        I have the same request as Allwyn. Also curious if I could possibly get a copy of the source code.


      • velab permalink
        15 Jul 2016 03:55

        Sir could you please share a sample source code for the above concept !


  3. cyril permalink
    28 Nov 2011 02:53

    GREAT paper !


  4. Mike permalink
    31 May 2012 01:00

    Great article. Does this approach also apply to the case when a 32-bit application needs to access a 64-bit DLL? In this case, the x64 surrogate process would load the 64-bit DLL, and the 32-bit application would make calls to a 32-bit wrapper DLL, which in turn communicates with the surrogate process. Thanks in advance.


    • Mike permalink
      26 Sep 2013 22:45

      Exactly, the mirrored way.


      • Marcel permalink
        1 Oct 2014 20:58

        Hi Mike,
        do you have a sample code that was provided with this article? I am trying to implement this by myself and it is failing. I am a student from Germany and need this for my studies. I can be contacted at the following email address:

        Thanks in Advance.


  5. Matt Nicholson permalink*
    31 May 2012 09:48

    Thanks! Unfortunately I’m no longer in contact with the author so I can’t help. I would however point out that the article is now five years old and may not be accurate for more recent versions of Windows.


  6. Varun Agarwal permalink
    1 Jun 2012 07:16

    HAtsOff! Very Knowledgefull article for a geek who is fresher in IT like me, I am highly thankfull to author.


  7. 12 Dec 2012 17:10

    Is there anyway an application after installing can intervene to COM? Having an problem make dll 32 bit can not access from dll 64 bit?


    • Mike permalink
      26 Sep 2013 22:46

      There are only a few scenarios, where the access is limited, mostly based on CAS of .NET. Please describe the problem more detailed. You may want to use ProcMon of Sysinternals and/or FUSLOGVW to diagnose the access problems


  8. Joselito permalink
    19 Apr 2013 14:05

    Great article!
    Thank you!!!


  9. Nicola Micheli permalink
    9 Oct 2014 16:26

    Hi Mike,
    great article, do you have a sample code?


  10. jiji permalink
    26 Dec 2014 09:37

    great article thank you
    can anyone help with the sample code plz ?
    thank you


  11. 30 Jul 2015 05:41

    Hi Sir,
    Can you recommend a book for COM technology.?


  12. 10 Sep 2015 08:08

    Hello Sir,
    Can you please provide me sample project for the article
    ” Accessing 32-bit DLLs from 64-bit code “.. I am struggling with similar situation.


  13. 21 Dec 2015 11:34

    I know this thread is getting old but getting the source code would help me out. Does anybody have it handy? I’d sure appreciate it!!


    • 21 Dec 2015 12:14

      As you say, this thread is getting old – the original post was written nearly eight years ago which is several lifetimes in the world of software! If anyone does have useful source code then I’m happy to link to it from here, but otherwise I’m afraid I can’t help.


    • Mike Becker permalink
      21 Dec 2015 12:17

      I hope, some of my archives should still keep at least a portion of code – ping me after XMas, I’m hittin’ the road


      • 21 Dec 2015 12:20

        Excellent! As I said, I’d be happy to link to it, or host the code here – whatever works best for you.


  14. 24 Dec 2015 14:24

    I got the source code from Marcel. Thanks Marcel!! At a high-ish level I understand the code. The COMServer project is almost EXACTLY what I want to do. I’m in VS 2012, not that it probably matters, but I would like to recreate this project. What are the steps? Start with IDL? Is there a Wizard in VIsual Studio? If I can recreate COMServer I’ll be in good shape.



  15. 24 Dec 2015 15:24

    Another question. What is the COMServerPS project about? What is PS?


  16. R Register permalink
    20 Apr 2016 18:54

    Yes I was very glad to find this article, and it is still useful despite all the time that has passed — thank you.
    And I want to pass along some additional ideas/information/resources that may still be helpful to others.
    On Windows7 and WIndows10, it is possible to use a 32-bit ActiveX control DLL or OCX — even though they are in-process — in your 64-bit application by making the so-called DllSurrogate modification, which is a straightforward change in the registry described here (Using a 32bit COM object in a 64bit environment):
    and described in a note from microsoft here (Registering the DLL Server for Surrogate Activation):

    I expect that this will work for many contexts like Visual Basic and C# and Visual Studio, but in my case i was actually able to drop an old 32-bit ActiveX control (with its own GUI and built in VisualStudio as a ActiveX DLL) onto a Delphi form at design time, and the resulting 64bit exe works the same as the 32bit exe (in fact both can run at the same time)!
    (Note that this was a Delphi XE8 design time form for a “VCL-Forms” application built for “64-bit Windows”).
    I also want to mention that the registry mod needed in my case was even simpler than described in the gfi article. In my case the AppID name was already defined in HKey_Classes_Root\Wow6432Node\CLSID\[myGUID] key — altho its string value was a differentGUID than myGUID, that didn’t cause problems — and so the only change necessary for me was to add the DllSurrogate string value to HKey_Classes_Root\Wow6432Node\AppID\[differentGUID] with an empty value as described. That was the only change necessary and i am still shocked that it seems to be working. I hope this is helpful to others.


  17. Alex permalink
    16 Nov 2016 19:50

    Great article!

    Could anyone send the sample code to my e-mail, please?

    Thank you a lot!


  18. 17 Nov 2016 14:15

    Hi Guys,

    Please do feel free to send me an email (lambeshatyahoodotcom) if you wish to have the source code, I know how hard it is to get it. I am more than happy to help you out as soon as I see your email.

    Good luck and warm regards,


  19. 24 Nov 2016 05:31

    An impressive share! I’ve just forwarded this onto a co-worker
    who had been doing a little homework on this. And he in fact bought me breakfast because I stumbled upon it
    for him… lol. So let me reword this…. Thanks
    for the meal!! But yeah, thanks for spending time to talk
    about this issue here on your internet site.


  20. Olivier Bertrand permalink
    18 Feb 2017 13:44

    It is like most of Microsoft doc: an article can seems good, but is not really good without code sample.


  21. Dave Pinella permalink
    29 Mar 2017 19:26

    What would the C# client look like in C++?? Thanks!


    • Mike Becker permalink
      29 Mar 2017 22:26

      Not much different. Check the code archive – there’s a x64client sample written in unmanaged C++. If you are looking for C++ managed – it would be very similar to C#.


      • Dave Pinella permalink
        30 Mar 2017 11:51

        Thanks Mike. Where are the code archives? I’m poking around. Thanks!


      • Dave Pinella permalink
        30 Mar 2017 11:54

        Sorry. Unmanaged is what I’m interested in.
        Dave P


      • Mike Becker permalink
        30 Mar 2017 11:56

        try now!As2tYxuPStfUqIBcjn9dd8xQ5gsxwA


      • Dave Pinella permalink
        30 Mar 2017 12:03

        I owe you one. Thanks!


      • Dave Pinella permalink
        30 Mar 2017 12:29

        Weird. The proxy stuff is all commented out in the x64 client. I uncommented them but the Ix86LibraryProxy is undefined. The import seems fine. How do I get this defined? IID_Ix86LibraryProxy is also undefined. As you can see, I’m a super noob with COM. I’m getting there though!


      • Mike Becker permalink
        31 Mar 2017 07:12

        yes, it is just sample – copied from earlier project – to explain the idea: import TLB, get automatically generated proxy classes, use them



  1. Com calls to 32bit application on 64bit server slow | - Developers Network
  2. How to run 32-bit AxInterop.DHTMLEDLib.dll in 64-bit win 7 operating system ? | 我爱源码网
  3. How to run 32-bit dll (AxInterop.DHTMLEDLib) in 64-bit win 7 operating system? | 我爱源码网
  4. Troubleshooting problems related to integrating with third party components « Philippsen's Blog
  5. Part 2. Support of 32-bit applications in the 64-bit Windows environment | How Not To Code

What do you think?

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: