A Worked Example of a COM Bridge for Calling a 64-bit DLL from a 32-bit App

· Updated: · · COM, Windows Development, 32bit, 64bit

Revision history (2 updates, last updated Sep 1, 2026)

A log of the changes made to this article. Where a pre-update version was archived, it stays readable at a permanent DOI link.

Retranslated as a full translation of the Japanese original. The previous English version was an abridgement that carried only part of the source, so sections, tables, Mermaid diagrams, figure captions and FAQ entries were missing. All of them have been restored to match the Japanese original, and the technical claims are the same as in the Japanese version. Read the version before this update (DOI: 10.5281/zenodo.22170260)
Added a paragraph ahead of section 3. If what you want to reach from the 64-bit side is itself an in-proc COM server (a DLL registered through InprocServer32), then adding an AppID to its CLSID and an empty DllSurrogate under that AppID hosts it in the dllhost.exe that ships with Windows, and you may not have to write an EXE server at all. It also notes that the surrogate which starts follows the bitness of the DLL rather than the client, and that a registered LocalServer32 means the surrogate is not used. When the thing you want to call is a plain native DLL, as in this article, there is no COM server to host in the first place, so the EXE-server approach described below is still required. The registration steps, and the line between what a surrogate covers and what needs an EXE of your own, are left to links to the other two articles. Read the version before this update (DOI: 10.5281/zenodo.21614447)
First published
Cite this article(DOI: 10.5281/zenodo.21614446)

This article is archived on Zenodo. Below are both the DOI that always resolves to the latest version and the DOI pinned to the version you are reading.

Go Komura (2026). A Worked Example of a COM Bridge for Calling a 64-bit DLL from a 32-bit App. KomuraSoft LLC. https://doi.org/10.5281/zenodo.21614446 https://comcomponent.com/en/blog/2026/01/25/002-com-case-study-32bit-to-64bit/

DOI (latest version)
10.5281/zenodo.21614446
DOI (this version)
10.5281/zenodo.22217115

Wanting to call a 64-bit DLL from a 32-bit app is a fairly typical requirement on Windows. Especially when you want to keep existing assets in place and use only the functionality on the 64-bit side, a COM bridge tends to be the practical answer.

Who this is for: Anyone maintaining an existing 32-bit Windows app who wants to use a DLL or library that lives on the 64-bit side. It is written so that you can follow it if you have heard of COM but have never built anything with it yourself.

Prerequisites: 64-bit Windows (x64) and a development environment where you can write C# (Visual Studio, for example). Registering a COM server machine-wide (under HKEY_LOCAL_MACHINE) requires administrator rights. The basic ideas behind COM are covered in “What Is COM? - Why the Design of Windows COM Is Still Beautiful Today”.

Table of Contents

  1. The Scenario
  2. The Solution
  3. Processing Flow (Sequence Diagram)
  4. Sample Code (Conceptual)
  5. Complete Sample Code
  6. Summary
  7. References

Knowledge map for this article

A 32-bit app cannot load a 64-bit DLL directly as in-proc COM because the bitness does not match, so this article separates the processing on the 64-bit side into another process as a COM LocalServer (an EXE server) and calls it in a typed way through a COM interface shared via IDL and a TypeLib. Marshaling and the proxy/stub bridge the calls that cross the process boundary, and the approach assumes registration of the CLSID and the ProgID, plus registration on both sides of the WOW64 registry redirector, where the CLSID subkey is separate in the 32-bit view and the 64-bit view. Registering for the whole machine requires administrator rights, and because the standard EnableComHosting in .NET (5 and later) is for in-proc only, the registration logic for an out-of-proc server has to be written yourself.

32-bit to 64-bit COM bridgeDiagram showing how an arrangement in which a 32-bit app calls a 64-bit DLL through a COM LocalServer EXE server relates to the type library, marshaling, CLSID and ProgID registration, and the WOW64 registry redirectorusesrequiresusesusesrequiresmitigatesrequiresrequiresrequiresstored inconfigured byrequiresrequiresnot recommended forrequiresusesnot recommended forrequiresuses32-bit/64-bit COM bridgeCOM LocalServer (out-of-process server)Type Library (TLB)MarshalingProxy/StubIn-Proc COM (DLL Server)Bitness Match RequirementCLSID (Class ID)ProgID (Programmatic Identifier)WOW64 Registry RedirectorWOW6432Nodereg.exe (/reg:32, /reg:64)Class Factory RegistrationAdministrator PrivilegesRegasm.exe.NET (Core and Later).NET Framework.NET 5+ COM Hosting (.comhost.dll)COM (Component Object Model)

In the diagram a solid line marks a relation that always holds and a dashed line marks a conditional one (the conditions are given per relation on the detail page). The full list of relations (19 in total, with evidence and certainty) and the definitions of the main concepts are collected on the knowledge map detail page (in Japanese). Data: JSON-LD / Turtle

1. The Scenario

You want to keep the existing 32-bit app exactly as it is, but use processing that lives in a 64-bit DLL. The problem is that a 32-bit process cannot load a 64-bit DLL. This is an OS-level constraint, not something you can work around with clever tricks.

The situation usually looks like this.

  • The existing 32-bit app is a large asset and cannot be migrated any time soon
  • The 64-bit DLL has new functionality, or its dependencies are 64-bit only
  • You want to call it from the 32-bit side with full type information

With this combination, the in-process route is closed off from the start.

The shape of the scenarioA diagram showing that an existing 32-bit app wants to use processing in a 64-bit DLL, but a 32-bit process cannot load a 64-bit DLL, an OS-level constraint that closes off the in-process route.Existing 32bit appWants to use processing in a 64bit DLLCannot be loaded in the same processAn OS-level constraint with no way around it

Figure 1: A 32-bit process cannot load a 64-bit DLL, so the in-process route never existed in the first place.

2. The Solution

This section leans on a fair amount of jargon, so here is the minimum vocabulary up front.

Term Meaning
In-proc COM (DLL server) Loading the COM component into the same process as the caller. Fast, but it cannot be loaded unless the bitness matches
Out-of-proc COM (EXE server) Running the COM component as a separate process. Works even when the bitness differs
LocalServer A COM server that runs as a separate process on the same PC. The path to the EXE goes into the registry under the LocalServer32 key
IDL / TypeLib The definition of the interface shape (method names, argument types) written in IDL, plus its binary form (TypeLib). Both sides use them to look at the same contract
Marshaling Repacking arguments and return values into a form that can travel across a process boundary. The reverse is unmarshaling
Proxy / Stub The stand-in code that actually performs the marshaling. A proxy sits on the caller side, a stub on the server side
WOW6432Node The place on 64-bit Windows where registry content for 32-bit apps physically lives. The same key name holds different content on the 32-bit and 64-bit sides

The basic solution is to separate the two with out-of-proc COM (an EXE server). The 64-bit DLL is called from a 64-bit COM server (an EXE), and the 32-bit app uses that server through COM.

Basic structure of the COM bridgeA diagram showing the separate-process structure in which a 32-bit app calls a 64-bit COM server EXE through COM and that server calls the 64-bit DLL internally.Calls through COMCalls internally32bit app64bit COM server (EXE)64bit DLL

Figure 2: The 64-bit DLL is hosted by a 64-bit EXE server, and the 32-bit app uses that server through COM.

The flow is as follows.

  1. Build a 64-bit COM LocalServer (an EXE) that calls the 64-bit DLL internally
  2. Share the COM interface (IDL/TypeLib) and expose the types
  3. The 32-bit app calls COM with full type information (the exchange goes through a proxy and marshaling)

There are caveats, though.

  • 32-bit and 64-bit registrations are separate (including WOW6432Node)
  • Custom structs require marshaling design
  • IPC overhead exists, so be careful with high-frequency calls

In short, the proven approach is to move the 64-bit processing into a separate process and bridge it with COM.

Three steps to build the bridgeA diagram showing the three-step flow of preparing a 64-bit COM LocalServer that calls the 64-bit DLL internally, exposing the interface types through IDL and TypeLib, and having the 32-bit app call it with full type information.Prepare a 64bit COM LocalServerExpose the types with IDL / TypeLibThe 32bit app calls it with type informationExchange goes through proxy / marshaling

Figure 3: The bridge comes together in three stages: prepare the LocalServer, expose the types, make typed calls.

That said, if what you want to use on the 64-bit side is already an in-proc COM server (a DLL registered under InprocServer32), you may be able to avoid writing an EXE server at all. Attach an AppID to the CLSID and write an empty-string DllSurrogate value under that AppID key, and the DLL is hosted in the surrogate process that ships with Windows (System32\dllhost.exe for a 64-bit DLL); to a 32-bit client it then looks like an out-of-proc COM server running in its own process (you are not registering the path of an EXE in LocalServer32 - in fact, if LocalServer32 is present, the surrogate is not used). The mechanism works the same way in the other direction (using a 32-bit COM DLL from a 64-bit app): the bitness of the surrogate that starts is decided by the DLL, not by the client. However, when the thing you want to call is just a plain native DLL, as in this article, there is no COM server to host in the surrogate in the first place, so you need the EXE server approach described from here on. The registration steps are in 3.5 of Registration and Bitness Pitfalls in COM/OCX/ActiveX Development (that article assumes a 32-bit DLL, so only the view you write the AppID value into needs to be read the other way round), and where to draw the line between a surrogate being enough and writing your own EXE is covered in 5.2 of How to Handle ActiveX / OCX Today - A Keep / Wrap / Replace Decision Table.

3. Processing Flow (Sequence Diagram)

The following shows the flow when the 32-bit app invokes processing in the 64-bit DLL.

Handled by the registered COM marshaling infrastructure64bit DLL64bit COM Server(EXE)COM Stub(64bit side)RPC/IPC(inter-process communication)COM Proxy(32bit side)32bit client app64bit DLL64bit COM Server(EXE)COM Stub(64bit side)RPC/IPC(inter-process communication)COM Proxy(32bit side)32bit client appMarshal the parametersUnmarshal the parametersMarshal the return valueUnmarshal the return valueICalcService.Add(1, 2)Serialized dataTransferred across the process boundaryAdd(1, 2)Native function callResult: 3Result: 3Serialized resultTransferred across the process boundaryResult: 3

Figure 4: The call from the 32-bit app travels through the proxy, inter-process communication, and the stub to reach the 64-bit server and the 64-bit DLL, and the result comes back along the same path.

Key points:

  • The 32-bit app can make type-safe calls through the ICalcService interface
  • The COM runtime crosses the process boundary using the registered proxy/stub DLL, the TypeLib marshaler, the standard marshaler, and so on
  • Because inter-process communication has overhead, batching work is preferable to many fine-grained calls
How to think about call granularityA diagram showing that because inter-process communication has overhead, repeating fine-grained calls at high frequency lets the cost pile up, so leaning toward batched processing is preferable.Overhead of inter-process communicationPiles up when fine-grained calls repeatHas little impact when work is batchedThis is the preferable side

Figure 5: Every crossing of the process boundary costs something, so it pays to group calls into a coarser granularity.

4. Sample Code (Conceptual)

4.1. The Shared Interface, the Server, and the Client

The following is a conceptual sketch. To make it run, you also need the registration described in 4.2.

// Shared interface (IDL equivalent)
[ComVisible(true)]
[Guid("7A4B5B23-0A2F-4D2B-9D4D-8A2A92B8B001")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface ICalcService
{
    int Add(int a, int b);
}

// 64bit COM LocalServer (EXE side)
[ComVisible(true)]
[Guid("1C9B6F4D-1E9A-4E61-9A4F-6A0F1D2D9A11")]
[ClassInterface(ClassInterfaceType.None)]
[ProgId("KomuraSoft.CalcService")]
public class CalcService : ICalcService
{
    public int Add(int a, int b)
    {
        // Call the 64bit DLL here
        return a + b;
    }
}

// 32bit app side (client)
Type t = Type.GetTypeFromProgID("KomuraSoft.CalcService");
var calc = (ICalcService)Activator.CreateInstance(t);
int result = calc.Add(1, 2);

With this shape, the 32-bit side gets to work with full type information. COM uses proxies and stubs internally and makes the call over IPC for you.

[ProgId("KomuraSoft.CalcService")] is there so that the client can find the class with Type.GetTypeFromProgID("KomuraSoft.CalcService"). A ProgID is nothing more than a human-readable alias; what actually locates the server is the CLSID registration described next.

From ProgID to the serverA diagram showing the resolution order in which the ProgID the client specifies is only a human-readable alias, the CLSID is looked up from it, and the CLSID registration is what locates the actual server.ProgID (human-readable alias)CLSID registrationThe server is found

Figure 6: The ProgID is the alias at the front door; what really points at the server is the CLSID registration.

4.2. The Minimum Registration Steps

COM works by having the COM runtime look up a CLSID in the registry and start the server it points to, so code that is not registered will never run (Type.GetTypeFromProgID returns null, or CreateInstance fails with REGDB_E_CLASSNOTREG). Boiled down, an EXE server (a LocalServer) needs only these three keys.

What you register Key Value
ProgID -> CLSID mapping HKEY_CLASSES_ROOT\KomuraSoft.CalcService\CLSID {1C9B6F4D-1E9A-4E61-9A4F-6A0F1D2D9A11}
CLSID -> path to the EXE HKEY_CLASSES_ROOT\CLSID\{1C9B6F4D-...}\LocalServer32 Full path to the 64-bit COM server EXE
CLSID -> ProgID reverse lookup HKEY_CLASSES_ROOT\CLSID\{1C9B6F4D-...}\ProgID KomuraSoft.CalcService

Here is the pitfall that is the very subject of this article. HKEY_LOCAL_MACHINE\SOFTWARE\Classes is shared between 32-bit and 64-bit apps, but Microsoft’s documentation states explicitly that the CLSID subkey underneath it (along with Interface and others) is separate for the 32-bit and 64-bit sides (the 32-bit side physically living in WOW6432Node). In other words, the ProgID key only has to be written once and both sides can see it, but unless the CLSID registration is written into both the 32-bit and the 64-bit view, a 32-bit client will not find the server.

Which parts of the registry are shared and which are splitA diagram showing that the ProgID key directly under Classes is visible from both 32-bit and 64-bit once written, while the entries under CLSID are separate per view and must be written to both, and that a missing 32-bit side means a 32-bit client cannot find the server.ProgID key (directly under Classes)Visible from both sidesRegistration under CLSIDWrite it in the 64bit viewWrite it in the 32bit viewPhysically stored in WOW6432NodeIf missing, invisible from 32bit

Figure 7: The ProgID key is shared, but everything under CLSID is per-view, so register it in both.

The reliable way is an administrator command prompt and the /reg:32 and /reg:64 switches of the reg command (writing Wow6432Node into the path yourself is something Microsoft discourages).

:: Run this in an administrator command prompt
set CLSID={1C9B6F4D-1E9A-4E61-9A4F-6A0F1D2D9A11}
set PROGID=KomuraSoft.CalcService
set SERVER=C:\Program Files\KomuraSoft\CalcServer.exe

:: 1) ProgID -> CLSID (everything directly under HKLM\SOFTWARE\Classes is shared by 32/64)
reg add "HKLM\SOFTWARE\Classes\%PROGID%\CLSID" /ve /d "%CLSID%" /f

:: 2) CLSID -> LocalServer32 and ProgID (entries under CLSID are separate for 32/64, so write both)
::    The LocalServer32 value must contain the executable path together with its quotes.
::    Writing /d "%SERVER%" makes reg.exe strip the quotes during argument parsing, and the
::    value is stored as plain C:\Program Files\... . COM interprets that as a command line,
::    so it first goes looking for C:\Program.exe, cut off at the space
reg add "HKLM\SOFTWARE\Classes\CLSID\%CLSID%\LocalServer32" /ve /d "\"%SERVER%\"" /f /reg:64
reg add "HKLM\SOFTWARE\Classes\CLSID\%CLSID%\ProgID"        /ve /d "%PROGID%"     /f /reg:64
reg add "HKLM\SOFTWARE\Classes\CLSID\%CLSID%\LocalServer32" /ve /d "\"%SERVER%\"" /f /reg:32
reg add "HKLM\SOFTWARE\Classes\CLSID\%CLSID%\ProgID"        /ve /d "%PROGID%"     /f /reg:32

:: Check the stored value. It is correct if it comes back quoted, as "C:\Program Files\..."
reg query "HKLM\SOFTWARE\Classes\CLSID\%CLSID%\LocalServer32" /ve /reg:64

The quotes around LocalServer32 are not just a matter of tidiness. Without them, C:\Program Files\... can legitimately be read as passing Files\... as an argument to C:\Program. As a result, in an environment where someone has the rights to create C:\Program.exe, that executable can be started instead. Always add quotes when the path contains a space.

How the presence of quotes changes the reading of LocalServer32A diagram showing that storing the path in LocalServer32 without quotes allows a reading that cuts it off at the space so that C:\Program.exe can be started first in an environment where that file can be placed, while storing it with quotes starts the intended EXE.Stored without quotesA reading that cuts off at the space becomes validC:\Program.exe can be started firstStored with quotesThe intended EXE is started

Figure 8: Registering a path containing a space without quotes leaves room for a different executable to be started.

Unregistering is just deleting the same keys.

set CLSID={1C9B6F4D-1E9A-4E61-9A4F-6A0F1D2D9A11}
set PROGID=KomuraSoft.CalcService

reg delete "HKLM\SOFTWARE\Classes\CLSID\%CLSID%" /f /reg:64
reg delete "HKLM\SOFTWARE\Classes\CLSID\%CLSID%" /f /reg:32
reg delete "HKLM\SOFTWARE\Classes\%PROGID%" /f

On top of that, the EXE has to announce to COM, when it starts, that it is the one serving this CLSID. In C/C++ that is CoRegisterClassObject; in .NET Framework it is RegistrationServices.RegisterTypeForComClients. Registry registration only takes care of getting COM to launch the EXE, so if this announcement is missing you get a confusing failure in which the EXE starts but no object can be created.

Registry registration and the EXE announcing itselfA diagram showing that registry registration only covers COM launching the EXE, that objects can be created only once the launched EXE announces it is serving this CLSID, and that a missing announcement produces a failure where the EXE starts but no object can be created.If the announcement is missingRegistry registrationCOM launches the EXEThe EXE announces it serves the CLSIDObjects can be createdIt starts but nothing can be created

Figure 9: Registry registration reaches as far as launching the EXE; beyond that, no object exists without the EXE announcing itself.

If you only need something to try during development, writing the same structure under HKCU\SOFTWARE\Classes instead of HKLM lets you register without administrator rights (HKEY_CLASSES_ROOT is a merged view of HKLM and HKCU). Note, though, that HKCU\SOFTWARE\Classes\CLSID is likewise handled separately for 32-bit and 64-bit, so you still have to write into both views.

4.3. .NET Framework and .NET (5 and Later) Are Built Differently

The code above is C#, but which .NET you use changes the procedure substantially. Mixing the two is where people get stuck.

  .NET Framework .NET (Core 3.0 / 5 and later)
Registration tool RegAsm.exe exists (but what it creates is an in-proc InprocServer32 registration, so you end up writing LocalServer32 yourself anyway) There is no equivalent of RegAsm
Standard way to expose COM Put attributes on the assembly and run RegAsm <EnableComHosting>true</EnableComHosting> generates *.comhost.dll, which you register with regsvr32 (in-proc only)
Generating a TypeLib (.tlb) Can be generated with TlbExp or RegAsm /tlb Not supported. Write the IDL by hand and compile it with MIDL (from .NET 6 on, the resulting .tlb can be embedded in the comhost)
Specifying the CLSID Optional An explicit CLSID is required for classes COM is meant to create
How AnyCPU behaves Usable from both 32-bit and 64-bit clients The accompanying *.comhost.dll is 64-bit by default, so it is usable only from 64-bit clients

The architecture in this article (an EXE server) falls outside what the standard EnableComHosting covers on .NET (5 and later), which means writing the registration logic yourself. Microsoft publishes an official sample, OutOfProcCOM, so that is the starting point if you build this on .NET.

The route to an EXE server on .NET (5 and later)A diagram showing that the EXE server architecture in this article falls outside the standard EnableComHosting on .NET 5 and later, so the registration logic has to be written by hand, with the official OutOfProcCOM sample as the starting point.EXE server on .NET (5 and later)Outside the scope of the standard EnableComHostingWrite the registration logic yourselfThe official OutOfProcCOM sample is the starting point

Figure 10: An EXE server on .NET (5 and later) sits outside the built-in feature set, so plan on writing the registration yourself.

5. Complete Sample Code

A working implementation of the concepts above is published on GitHub.

Call64bitDLLFrom32bitProc - GitHub

The repository contains the following:

  • Call64bitDLLFrom32bitProc/ - 64bit COM LocalServer (EXE)
  • X64DLL/ - 64bit DLL (the actual processing)
  • X86App/ - 32bit client (WinForms)
  • scripts/ - COM server registration and unregistration scripts

If you build and register it following the steps in the README, you can watch a 32-bit process actually call a 64-bit DLL.

6. Summary

A COM bridge is not a universal answer; it is an architecture where the jobs it suits and the jobs it does not are clearly separated. Before committing to it, hold your own case up against the table below.

Cases it suits Cases it does not suit
The 32-bit app itself cannot be rebuilt (the cost of reworking it does not pay off) The 32-bit side can simply be rebuilt as 64-bit (that is the shortest path)
Calls are coarse-grained (one image per call, one file per call, and so on) Tens of thousands of calls one element at a time, or any high-frequency fine-grained pattern (IPC overhead dominates)
What you exchange are numbers, strings, arrays, and other types that marshal easily Raw pointers or complex custom structs shuttled back and forth in bulk
You want the app itself to stay alive even when the 64-bit processing crashes (process isolation becomes an advantage) You do not want to write recovery logic for server crashes and restarts
You want to keep typed calls (IntelliSense and compile-time checking) A one-shot batch job is enough, and passing data through standard I/O or files will do

As the flip side of that last row, the plain alternative of making the 64-bit processing a simple console EXE and exchanging data through arguments and files is always worth considering. A COM bridge earns its keep when you want to keep typed calls and when you want to call a stateful server repeatedly.

Where the COM bridge and the plain alternative divergeA diagram showing the dividing line where a COM bridge earns its place if typed calls must be kept or a stateful server has to be called repeatedly, while a one-shot batch job is better served by the plain alternative of a console EXE exchanging data through arguments and files.YesNoAre typed calls or retained state required?COM bridgeConsole EXE passing arguments and files

Figure 11: Whether you need typed calls and retained state is what separates the bridge from the plain alternative.

For next steps, here is the order I recommend.

  1. First, clone the sample repository from section 5, build and register it exactly as the README says, and get one working setup in your own hands.
  2. Pick a single function from your own 64-bit DLL and add one method to the interface that corresponds to the sample’s ICalcService, then get it working end to end.
  3. Once it works, measure how many calls you make and how much data each one carries. Settling the design decision to move toward coarse granularity here (merging several calls into one) up front saves you from backtracking later.

7. References

  • Component Object Model (COM) overview https://learn.microsoft.com/en-us/windows/win32/com/component-object-model–com–portal
  • Registering COM LocalServer32 https://learn.microsoft.com/en-us/windows/win32/com/localserver32
  • COM interface basics https://learn.microsoft.com/en-us/windows/win32/com/the-component-object-model
  • COM Interop (use from .NET) https://learn.microsoft.com/en-us/dotnet/standard/native-interop/cominterop
  • The WOW64 registry redirector (HKLM\SOFTWARE\Classes is shared, entries under CLSID are separate for 32/64) https://learn.microsoft.com/en-us/windows/win32/winprog64/shared-registry-keys
  • Exposing .NET (Core / 5 and later) components to COM https://learn.microsoft.com/en-us/dotnet/core/native-interop/expose-components-to-com

Recent articles sharing the same tags. Deepen your understanding with closely related topics.

These topic pages place the article in a broader service and decision context.

This article connects naturally to the following service pages.

Frequently Asked Questions

Common questions about the topic of this article.

Can I call a 64-bit DLL directly from a 32-bit app?
No. A 32-bit process cannot load a 64-bit DLL. This is an OS-level constraint, not something you can work around with clever tricks. The in-process route is closed off from the start, so you need an architecture that moves the 64-bit processing into a separate process.
How can I use the functionality of a 64-bit DLL from a 32-bit app?
The proven approach is to separate the two with out-of-proc COM (an EXE server). The 64-bit DLL is called from a 64-bit COM LocalServer (an EXE), and the 32-bit app uses it through a COM interface with full type information. You share the COM interface (IDL/TypeLib) to expose the types, and the COM runtime crosses the boundary for you with proxies, stubs, and inter-process communication.
What should I watch out for with a COM bridge architecture?
There are three main points. 32-bit and 64-bit registrations are separate (including WOW6432Node), custom structs require marshaling design, and inter-process communication adds overhead, so high-frequency fine-grained calls need care. Rather than pushing large numbers of small calls through the bridge, lean toward batching the work.
Is there sample code that actually runs?
Yes. The Call64bitDLLFrom32bitProc repository on GitHub publishes a complete sample that includes a 64-bit COM LocalServer (EXE), a 64-bit DLL, a 32-bit client (WinForms), and scripts for registering and unregistering the COM server. Build and register it following the steps in the README, and you can watch a 32-bit process call a 64-bit DLL.

Author Profile

Profile page for the article author.

Go Komura

Representative of KomuraSoft LLC

Focused on Windows software development, technical consulting, and investigations into failures that are difficult to reproduce.

Back to the Blog