Esempio pratico di un ponte COM per chiamare una DLL a 64 bit da un'applicazione a 32 bit
· Aggiornato il: · Go Komura · COM, Sviluppo Windows, 32 bit, 64 bit
Cronologia delle revisioni (prima versione, pubblicata il 25 Jan 2026)
- Prima pubblicazione
Citare questo articolo(DOI: 10.5281/zenodo.22170262)
Questo articolo è archiviato su Zenodo. Qui sotto trovi sia il DOI che rimanda sempre all'ultima versione sia quello fissato alla versione che stai leggendo.
Go Komura (2026). Esempio pratico di un ponte COM per chiamare una DLL a 64 bit da un'applicazione a 32 bit. KomuraSoft LLC. https://doi.org/10.5281/zenodo.22170262 https://comcomponent.com/it/blog/2026/01/25/002-com-case-study-32bit-to-64bit/
- DOI (ultima versione)
- 10.5281/zenodo.22170262
- DOI (questa versione)
- 10.5281/zenodo.22170263
Volere chiamare una DLL a 64 bit da un’applicazione a 32 bit è un’esigenza abbastanza comune su Windows. Soprattutto quando si vogliono mantenere in sede asset esistenti e usare solo la funzionalità del lato a 64 bit, un’architettura a ponte COM tende a essere la risposta pratica.
Indice
- Lo scenario
- La soluzione
- Flusso di elaborazione (diagramma di sequenza)
- Codice di esempio (concettuale)
- Codice di esempio completo
- Riferimenti
1. Lo scenario
Questo è il caso in cui si vuole mantenere un’applicazione a 32 bit così com’è, ma usare un’elaborazione che risiede in una DLL a 64 bit. Il problema è che un processo a 32 bit non può caricare una DLL a 64 bit. È un vincolo a livello di sistema operativo: non si può aggirare con trucchi.
La situazione tipica è questa.
- L’applicazione a 32 bit esistente è un asset di grandi dimensioni e non può essere migrata a breve
- La DLL a 64 bit ha nuove funzionalità, oppure le sue dipendenze sono solo a 64 bit
- Si vuole chiamarla dal lato a 32 bit “con i tipi”
Con questa combinazione, la strada in-process è chiusa fin dall’inizio.
2. La soluzione
La soluzione di base è separare tramite COM out-of-process (un server EXE). La DLL a 64 bit viene chiamata da un server COM a 64 bit (EXE), e l’applicazione a 32 bit la utilizza tramite COM.
Il flusso è il seguente.
- Costruire un COM LocalServer a 64 bit (EXE) che chiama internamente la DLL a 64 bit
- Condividere l’interfaccia COM (IDL/TypeLib) per esporre i tipi
- L’applicazione a 32 bit chiama COM “con i tipi” (comunicando tramite proxy/marshaling)
Ci sono comunque delle avvertenze.
- Le registrazioni a 32 bit e a 64 bit sono separate (incluso WOW6432Node)
- Le strutture personalizzate richiedono una progettazione di marshaling
- Esiste un overhead IPC, quindi fare attenzione alle chiamate ad alta frequenza
In sintesi, l’approccio collaudato è “spostare l’elaborazione a 64 bit in un processo separato e collegarla con COM”.
Se poi ciò che si vuole usare sul lato a 64 bit è già di per sé un server COM in-process (una DLL registrata tramite InprocServer32), può capitare di non dover scrivere alcun server EXE. Assegnando un AppID al CLSID e scrivendo in quella chiave AppID un DllSurrogate con valore stringa vuota, quella DLL viene ospitata nel processo surrogato fornito con Windows (per una DLL a 64 bit, System32\dllhost.exe) e dal client a 32 bit appare come un server COM out-of-process che gira in un processo separato (non si tratta di registrare il percorso di un EXE in LocalServer32; anzi, se LocalServer32 è presente il surrogato non viene usato). Anche nella direzione opposta (usare una DLL COM a 32 bit da un’applicazione a 64 bit) il meccanismo è lo stesso, e la bitness del surrogato che viene avviato è determinata dal lato della DLL, non dal client. Tuttavia, se come in questo articolo ciò che si vuole chiamare è una semplice DLL nativa, non esiste alcun server COM da ospitare nel surrogato, quindi serve l’approccio con server EXE descritto nel seguito. La procedura di registrazione è riassunta nel 3.5 di Registration and Bitness Pitfalls in COM/OCX/ActiveX Development (là si presuppone una DLL a 32 bit, quindi basta reinterpretare la view in cui si scrive il valore AppID), mentre il criterio per stabilire se basta il surrogato o se occorre scrivere un EXE proprio è riassunto nel 5.2 di Come gestire ActiveX / OCX oggi - Una tabella decisionale Mantieni / Avvolgi / Sostituisci.
3. Flusso di elaborazione (diagramma di sequenza)
Di seguito il flusso quando l’applicazione a 32 bit invoca l’elaborazione nella DLL a 64 bit.
sequenceDiagram
participant App as App client 32 bit
box rgba(100,100,255,0.1) Gestito dall'infrastruttura di marshaling COM registrata
participant Proxy as Proxy COM<br/>(lato 32 bit)
participant RPC as RPC/IPC<br/>(comunicazione inter-processo)
participant Stub as Stub COM<br/>(lato 64 bit)
end
participant Server as Server COM 64 bit<br/>(EXE)
participant DLL as DLL 64 bit
App->>Proxy: ICalcService.Add(1, 2)
rect rgba(100,100,255,0.1)
Note over Proxy: Esegue il marshaling dei parametri
Proxy->>RPC: Dati serializzati
RPC->>Stub: Trasferiti attraverso il confine di processo
Note over Stub: Esegue l'unmarshaling dei parametri
end
Stub->>Server: Add(1, 2)
Server->>DLL: Chiamata a funzione nativa
DLL-->>Server: Risultato: 3
Server-->>Stub: Risultato: 3
rect rgba(100,100,255,0.1)
Note over Stub: Esegue il marshaling del valore di ritorno
Stub-->>RPC: Risultato serializzato
RPC-->>Proxy: Trasferito attraverso il confine di processo
Note over Proxy: Esegue l'unmarshaling del valore di ritorno
end
Proxy-->>App: Risultato: 3
Punti chiave:
- L’applicazione a 32 bit può effettuare chiamate type-safe attraverso l’interfaccia
ICalcService - Il runtime COM attraversa il confine di processo usando la DLL proxy/stub registrata, il marshaler della libreria dei tipi, il marshaler standard e così via
- A causa dell’overhead della comunicazione inter-processo, è preferibile raggruppare il lavoro anziché fare molte chiamate a grana fine
4. Codice di esempio (concettuale)
Di seguito uno schizzo concettuale. In pratica servono anche registrazione, generazione della TypeLib e così via.
// Interfaccia condivisa (equivalente IDL)
[ComVisible(true)]
[Guid("7A4B5B23-0A2F-4D2B-9D4D-8A2A92B8B001")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface ICalcService
{
int Add(int a, int b);
}
// COM LocalServer a 64 bit (lato EXE)
[ComVisible(true)]
[Guid("1C9B6F4D-1E9A-4E61-9A4F-6A0F1D2D9A11")]
[ClassInterface(ClassInterfaceType.None)]
public class CalcService : ICalcService
{
public int Add(int a, int b)
{
// Qui viene chiamata la DLL a 64 bit
return a + b;
}
}
// Lato app a 32 bit (client)
Type t = Type.GetTypeFromProgID("KomuraSoft.CalcService");
var calc = (ICalcService)Activator.CreateInstance(t);
int result = calc.Add(1, 2);
Con questa forma, il lato a 32 bit può lavorare “con i tipi”. COM usa proxy/stub internamente ed effettua la chiamata su IPC per noi.
5. Codice di esempio completo
Un’implementazione funzionante del concetto sopra è pubblicata su GitHub.
Call64bitDLLFrom32bitProc - GitHub
Il repository contiene quanto segue:
- Call64bitDLLFrom32bitProc/ - COM LocalServer a 64 bit (EXE)
- X64DLL/ - DLL a 64 bit (l’elaborazione effettiva)
- X86App/ - Client a 32 bit (WinForms)
- scripts/ - Script di registrazione/deregistrazione del server COM
Se lo si compila e registra seguendo i passaggi del README, si può vedere un processo a 32 bit che chiama effettivamente una DLL a 64 bit.
6. Riferimenti
- 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
Articoli correlati
Articoli recenti con gli stessi tag per approfondire argomenti vicini.
Come funzionano gli Appunti e il trascinamento della selezione — Gestire correttamente il trasferimento dati OLE nelle app aziendali
Incollate una tabella Excel e la formattazione si sfascia; chiudete l'app di origine e non potete più incollare — entrambi vengono dal fa...
L'integrazione con la shell di Windows oggi ── menu contestuali, associazioni di file e cosa è cambiato in Windows 11
Perché il menu contestuale di Windows 11 nasconde le voci dietro «Mostra altre opzioni»: dalle basi estensione → ProgID → verb alle caute...
Fino a quando funzioneranno le applicazioni VB6? — Lo stato del supporto al runtime e un percorso pratico verso la migrazione a .NET
Fino a quando continueranno a funzionare le applicazioni VB6? Questo articolo chiarisce l'asimmetria tra la politica di supporto del runt...
Outsourcing e sviluppo su commissione di app Windows: cosa chiarire prima di affidare l'incarico
Prima di affidare in outsourcing o su commissione lo sviluppo di un'app Windows, ecco i punti da chiarire: revisione del software esisten...
Il curioso amore di uno sviluppatore, ovvero: come ho imparato a non preoccuparmi e ad amare Windows
Windows è complicato. Ma questa complicazione è anche quella di un sistema operativo che da decenni porta sulle spalle il lavoro reale.
Argomenti correlati
Queste pagine collocano l’argomento in un contesto più ampio di servizi e decisioni.
Argomenti tecnici Windows
Portale su sviluppo Windows, analisi dei problemi e valorizzazione delle risorse esistenti.
Migrazione ActiveX
Scelte per mantenere, incapsulare o sostituire componenti COM / ActiveX / OCX.
Servizi collegati all’argomento
L’articolo è direttamente collegato ai servizi seguenti.
Riutilizzo e migrazione delle risorse esistenti
Si tratta di costruire un ponte verso il lato a 64 bit mantenendo in sede gli asset a 32 bit, rientra direttamente nel supporto alla riutilizzazione e migrazione di asset legacy.
Consulenza tecnica e revisione del progetto
Se si vuole prima chiarire la progettazione del ponte COM o dove tracciare i confini dei processi, possiamo confrontare le opzioni insieme attraverso consulenza tecnica e design review.
Domande frequenti
Domande che ricorrono nelle consulenze sull’argomento dell’articolo.
- Un'applicazione a 32 bit può caricare una DLL a 64 bit?
- No. Un processo a 32 bit non può caricare una DLL a 64 bit: è un vincolo a livello di sistema operativo su Windows, non qualcosa che si possa aggirare con trucchi. La strada in-process è chiusa fin dall'inizio. Se serve la funzionalità che risiede in una DLL a 64 bit, l'elaborazione deve essere eseguita in un processo separato a 64 bit, e un ponte COM è un modo collaudato per collegare i due.
- Come collega un ponte COM un'applicazione a 32 bit a una DLL a 64 bit?
- Si costruisce un COM LocalServer a 64 bit (un EXE) che chiama internamente la DLL a 64 bit, si condivide l'interfaccia COM tramite IDL o una libreria dei tipi per esporre i tipi, e l'applicazione a 32 bit la utilizza attraverso COM. Il runtime COM attraversa il confine dei processi usando proxy, stub e marshaling, quindi il lato a 32 bit può effettuare chiamate type-safe attraverso l'interfaccia condivisa.
- Quali sono i principali avvertenze quando si usa un ponte COM out-of-process?
- Ce ne sono tre principali. Primo, le registrazioni COM a 32 bit e a 64 bit sono separate, inclusa l'area di registro WOW6432Node. Secondo, le strutture personalizzate richiedono una progettazione di marshaling anziché funzionare automaticamente. Terzo, la comunicazione inter-processo aggiunge overhead a ogni chiamata, quindi è preferibile raggruppare il lavoro anziché fare molte chiamate a grana fine in scenari ad alta frequenza.
- Esiste un esempio funzionante di ponte COM da 32 a 64 bit?
- Sì. Un'implementazione completa e funzionante è pubblicata su GitHub come repository Call64bitDLLFrom32bitProc. Contiene un COM LocalServer a 64 bit (EXE), una DLL a 64 bit con l'elaborazione effettiva, un client WinForms a 32 bit e script di registrazione del server COM. Se lo si compila e registra seguendo il README, si può vedere un processo a 32 bit che chiama effettivamente una DLL a 64 bit.
Profilo dell’autore
Pagina di presentazione dell’autore dell’articolo.
Go Komura
Rappresentante di KomuraSoft LLC
Specializzato nello sviluppo di software Windows, nella consulenza tecnica e nell’analisi dei malfunzionamenti, soprattutto nei progetti con sistemi esistenti e guasti difficili da riprodurre.