A Worked Example of a COM Bridge for Calling a 64-bit DLL from a 32-bit App
· Go Komura · COM, Windows Development, 32bit, 64bit
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 64-bit side’s functionality, a COM bridge architecture tends to be the practical answer.
Table of Contents
- The Scenario
- The Solution
- Processing Flow (Sequence Diagram)
- Sample Code (Conceptual)
- Complete Sample Code
- References
1. The Scenario
This is the case where you want to keep an existing 32-bit app as 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 - it is not something you can work around with clever tricks.
The typical situation 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 types”
With this combination, the in-process route is closed off from the start.
2. The Solution
The basic solution is to separate via out-of-proc COM (an EXE server). The 64-bit DLL is called from a 64-bit COM server (EXE), and the 32-bit app uses it through COM.
The flow is as follows.
- Build a 64-bit COM LocalServer (EXE) that calls the 64-bit DLL internally
- Share the COM interface (IDL/TypeLib) to expose the types
- The 32-bit app calls COM “with types” (communicating via proxy/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.”
3. Processing Flow (Sequence Diagram)
The following shows the flow when the 32-bit app invokes processing in the 64-bit DLL.
sequenceDiagram
participant App as 32bit client app
box rgba(100,100,255,0.1) Handled by the registered COM marshaling infrastructure
participant Proxy as COM Proxy<br/>(32bit side)
participant RPC as RPC/IPC<br/>(inter-process communication)
participant Stub as COM Stub<br/>(64bit side)
end
participant Server as 64bit COM Server<br/>(EXE)
participant DLL as 64bit DLL
App->>Proxy: ICalcService.Add(1, 2)
rect rgba(100,100,255,0.1)
Note over Proxy: Marshal the parameters
Proxy->>RPC: Serialized data
RPC->>Stub: Transferred across the process boundary
Note over Stub: Unmarshal the parameters
end
Stub->>Server: Add(1, 2)
Server->>DLL: Native function call
DLL-->>Server: Result: 3
Server-->>Stub: Result: 3
rect rgba(100,100,255,0.1)
Note over Stub: Marshal the return value
Stub-->>RPC: Serialized result
RPC-->>Proxy: Transferred across the process boundary
Note over Proxy: Unmarshal the return value
end
Proxy-->>App: Result: 3
Key points:
- The 32-bit app can make type-safe calls through the
ICalcServiceinterface - The COM runtime crosses the process boundary using the registered proxy/stub DLL, the TypeLib marshaler, the standard marshaler, and so on
- Because of the inter-process communication overhead, batching work is preferable to many fine-grained calls
4. Sample Code (Conceptual)
The following is a conceptual sketch. In practice you also need registration, TypeLib generation, and so on.
// 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)]
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 can work “with types.” COM uses proxies/stubs internally and makes the call over IPC for you.
5. Complete Sample Code
A working implementation of the concept 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/unregistration scripts
If you build and register it following the steps in the README, you can see a 32-bit process actually calling a 64-bit DLL.
6. References
- Component Object Model (COM) overview https://learn.microsoft.com/en-us/windows/win32/com/component-object-model–com–portal
- COM LocalServer32 registration 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
Related Articles
Recent articles sharing the same tags. Deepen your understanding with closely related topics.
Registration and Bitness Pitfalls in COM/OCX/ActiveX Development
A practical look at the pitfalls of COM, OCX, and ActiveX development: 32bit/64bit, Visual Studio 2022, regsvr32/Regasm, administrator ri...
Why ActiveX Stops Working in Office 2024/Microsoft 365 and How to Diagnose It
When ActiveX stops working in Office 2024/Microsoft 365, work through the causes in order: default disablement, 32-bit/64-bit mismatch, C...
Windows App Outsourcing and Contract Development: What to Sort Out Before You Ask
Before commissioning Windows app outsourcing or contract development, here is how to sort out existing software modification, device inte...
A Developer's Strange Love, or: How I Learned to Stop Worrying and Love Windows
Windows is a hassle. But that hassle is the hassle of an OS that has carried real-world business on its back.
What Is Reg-Free COM - Using COM Without Registration
An overview of Reg-Free COM basics, the roles of activation contexts and manifests, the benefits, the limitations, and how to decide when...
Related Topics
These topic pages place the article in a broader service and decision context.
Windows Technical Topics
Topic hub for KomuraSoft LLC's Windows development, investigation, and legacy-asset articles.
ActiveX Migration
Topic page for staged decisions around keeping, wrapping, or replacing COM / ActiveX / OCX assets.
Where This Topic Connects
This article connects naturally to the following service pages.
Legacy Asset Reuse & Migration Support
This is about building a bridge to the 64-bit side while keeping 32-bit assets in place, so it ties directly into our legacy asset reuse and migration support.
Technical Consulting & Design Review
If you first want to sort out the COM bridge design or where to draw process boundaries, we can compare options together through technical consulting and design review.
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.
Public links