Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Catalog · How the catalog works
Anything · Lazarus or Delphi
Random projectRandom project

6432Proxy

View on GitHub

Member rating

No ratings yet.

Sign in to rate this project.

README

6432Proxy

A small Delphi demo that shows a practical workaround for a classic Windows limitation:

a 64-bit process cannot load a 32-bit DLL directly

Instead of loading the DLL in-process, this repository runs the 32-bit DLL inside a separate 32-bit proxy process and lets a 64-bit client talk to that proxy through inter-process communication (IPC).

This project is intentionally simple and focused. It uses a tiny AddNumbers function as the sample workload, but the same pattern can be extended to wrap real legacy 32-bit DLLs from a modern 64-bit Delphi application.


Why this exists

On Windows, a process can only load DLLs that match its own bitness.

That means:

  • a 32-bit application can load a 32-bit DLL
  • a 64-bit application can load a 64-bit DLL
  • a 64-bit application cannot load a 32-bit DLL
  • a 32-bit application cannot load a 64-bit DLL

When you still depend on an old 32-bit vendor SDK, hardware driver wrapper, or legacy DLL, one clean workaround is to move that dependency into a separate helper process and communicate with it over IPC.

That is exactly what this repository demonstrates.


Repository structure

This project group contains three main parts:

1. Sample32.dll

A very small 32-bit DLL used only for demonstration.

It exports:

  • AddNumbers(A, B: Integer): Integer

For the demo, it simply returns A + B.


2. ProxyServer

A 32-bit console application that acts as the bridge between the 64-bit world and the 32-bit DLL.

Responsibilities:

  • loads Sample32.dll
  • resolves the exported AddNumbers function
  • exposes that function to external callers through IPC
  • stays alive until the user presses Enter

It supports two IPC channels:

  • Named Pipe
  • Windows messaging via WM_COPYDATA

3. Client64

A 64-bit VCL application that calls the proxy instead of loading the DLL directly.

It provides a tiny UI where you enter two integers and test both communication methods:

  • Pipe
  • CopyData

If everything is running correctly, both paths should return the same result.

Example:

  • Input: 10 and 20
  • Output: 30

Communication modes

1) Named Pipe mode

The named pipe channel is the more explicit and scalable IPC option in this sample.

Flow:

  1. Client64 connects to the pipe
  2. it sends two integers
  3. ProxyServer receives them
  4. ProxyServer calls the 32-bit DLL
  5. the integer result is sent back through the pipe

Pipe name used in this demo:

text
\\.\pipe\Proxy32BitPipe

This approach is usually the better foundation when:

  • you want a clearer request/response model
  • you plan to send more structured data later
  • you may extend the protocol beyond a single integer result

2) WM_COPYDATA mode

The second channel uses a hidden window in the 32-bit proxy and sends requests via WM_COPYDATA.

Flow:

  1. Client64 finds the hidden proxy window
  2. it sends a packed request with WM_COPYDATA
  3. ProxyServer extracts the request
  4. the proxy calls the DLL
  5. the result is returned as the message result

This is useful as a lightweight Windows-only IPC option, especially for small payloads and simple request patterns.


How it works

At a high level, the architecture looks like this:

text
+-------------------+           IPC            +-------------------+         LoadLibrary         +------------------+
|   Client64.exe    |  -------------------->   |  ProxyServer.exe  |  ----------------------->  |   Sample32.dll   |
|   (64-bit VCL)    |   Pipe / WM_COPYDATA     |   (32-bit)        |    GetProcAddress         |   (32-bit DLL)   |
+-------------------+                           +-------------------+                            +------------------+
         ^                                               |
         |-------------------- result -------------------|

The key idea is simple:

  • the 64-bit app never touches the 32-bit DLL directly
  • the 32-bit proxy becomes the only process that loads and executes the legacy DLL
  • IPC becomes the boundary between the two worlds

What this demo proves

This repository demonstrates that a 64-bit Delphi application can still use a 32-bit-only DLL by moving that DLL behind a 32-bit proxy boundary.

It is a useful pattern when dealing with:

  • legacy vendor SDKs
  • old hardware access libraries
  • abandoned 32-bit third-party DLLs
  • migration projects where the main app must be 64-bit, but some dependencies are not

Notes and limitations

This is a focused demo, not a production IPC framework.

A real-world version would likely add things such as:

  • structured request/response packets
  • error propagation
  • timeouts and reconnect logic
  • versioning of the IPC protocol
  • support for multiple exported functions
  • marshaling of strings, records, arrays, and binary buffers
  • logging and diagnostics
  • graceful shutdown and worker lifecycle management
  • thread-safe or multi-client handling depending on workload

When to choose each IPC approach

Named Pipes

Choose pipes when you want:

  • a clearer protocol
  • more room for future growth
  • bidirectional data exchange
  • easier expansion to larger or more complex payloads

WM_COPYDATA

Choose WM_COPYDATA when you want:

  • very lightweight IPC
  • small request payloads
  • a simple Windows GUI/message-based integration

For most non-trivial growth paths, named pipes are usually the stronger long-term option.


If you need more/deeper IPC framework then have a look at this repository

https://github.com/AliDehbansiahkarbon/IPCFramework4D

License

This project is licensed under the MIT License. See LICENSE.


Author

Ali Dehbansiahkarbon


Delphi

Made with :heart: in Delphi