Un exemple concret de pont COM pour appeler une DLL 64 bits depuis une application 32 bits

· Mis à jour le: · · COM, Développement Windows, 32bit, 64bit

Historique des révisions (1 mises à jour, dernière le 30 Aug 2026)

Journal des modifications apportées à cet article. Lorsqu'une version antérieure a été archivée, elle reste consultable via un lien permanent avec DOI.

Ajout d'un paragraphe avant la section 3. Si ce que vous voulez atteindre depuis le côté 64 bits est lui-même un serveur COM in-proc (une DLL enregistrée via InprocServer32), il suffit d'ajouter un AppID à son CLSID et un DllSurrogate vide sous cet AppID pour l'héberger dans le dllhost.exe fourni avec Windows, et il devient parfois inutile d'écrire un serveur EXE. Le paragraphe précise aussi que le surrogate qui démarre suit la bitness de la DLL et non celle du client, et qu'un LocalServer32 enregistré fait que le surrogate n'est pas utilisé. En revanche, lorsque ce que l'on veut appeler est une simple DLL native, comme dans cet article, il n'y a pas de serveur COM à héberger, et l'approche par serveur EXE décrite plus loin reste nécessaire. La procédure d'enregistrement, ainsi que la limite entre ce que couvre un surrogate et ce qui exige son propre EXE, sont laissées à des liens vers les deux autres articles. Lire la version antérieure à cette mise à jour (DOI: 10.5281/zenodo.21618315)
Première publication
Citer cet article(DOI: 10.5281/zenodo.21618314)

Cet article est archivé sur Zenodo. Vous trouverez ci-dessous le DOI qui renvoie toujours à la dernière version et celui qui est figé sur la version que vous lisez.

Go Komura (2026). Un exemple concret de pont COM pour appeler une DLL 64 bits depuis une application 32 bits. KomuraSoft LLC. https://doi.org/10.5281/zenodo.21618314 https://comcomponent.com/fr/blog/2026/01/25/002-com-case-study-32bit-to-64bit/

DOI (dernière version)
10.5281/zenodo.21618314
DOI (cette version)
10.5281/zenodo.22170261

Vouloir appeler une DLL 64 bits depuis une application 32 bits est une exigence assez classique sous Windows. Notamment lorsqu’on souhaite conserver les ressources existantes en place et n’utiliser que les fonctionnalités du côté 64 bits, une architecture en pont COM tend à être la réponse pratique.

Sommaire

  1. Le scénario
  2. La solution
  3. Déroulement du traitement (diagramme de séquence)
  4. Exemple de code (conceptuel)
  5. Exemple de code complet
  6. Références

1. Le scénario

C’est le cas où l’on souhaite conserver une application 32 bits existante telle quelle, mais utiliser un traitement qui réside dans une DLL 64 bits. Le problème est qu’un processus 32 bits ne peut pas charger une DLL 64 bits. Il s’agit d’une contrainte au niveau du système d’exploitation - ce n’est pas quelque chose que l’on peut contourner par une astuce quelconque.

La situation typique ressemble à ceci.

  • L’application 32 bits existante est un actif volumineux qui ne peut pas être migré à court terme
  • La DLL 64 bits possède de nouvelles fonctionnalités, ou ses dépendances sont exclusivement 64 bits
  • On souhaite l’appeler depuis le côté 32 bits « de façon typée »

Avec cette combinaison, la voie in-process est fermée dès le départ.

2. La solution

La solution de base consiste à séparer via un COM out-of-proc (un serveur EXE). La DLL 64 bits est appelée depuis un serveur COM 64 bits (EXE), et l’application 32 bits l’utilise via COM.

Le déroulement est le suivant.

  1. Construire un COM LocalServer 64 bits (EXE) qui appelle la DLL 64 bits en interne
  2. Partager l’interface COM (IDL/TypeLib) pour exposer les types
  3. L’application 32 bits appelle COM « de façon typée » (communication via proxy/marshaling)

Il existe toutefois des points d’attention.

  • Les enregistrements 32 bits et 64 bits sont distincts (y compris WOW6432Node)
  • Les structures personnalisées nécessitent une conception de marshaling
  • La surcharge de l’IPC existe, donc soyez attentif aux appels à haute fréquence

En bref, l’approche éprouvée consiste à « déplacer le traitement 64 bits vers un processus séparé et faire le pont avec COM ».

Notez par ailleurs que si ce que l’on souhaite utiliser du côté 64 bits est à l’origine un serveur COM in-process (une DLL enregistrée via InprocServer32), il est parfois possible de se passer d’écrire un serveur EXE. En attribuant un AppID au CLSID et en écrivant dans cette clé AppID une valeur DllSurrogate vide (une chaîne vide), la DLL est chargée dans le processus surrogate fourni avec Windows (System32\dllhost.exe pour une DLL 64 bits) et apparaît au client 32 bits comme un serveur COM out-of-proc s’exécutant dans un processus séparé (il ne s’agit pas d’enregistrer le chemin d’un EXE dans LocalServer32 ; au contraire, si LocalServer32 est présent, le surrogate n’est pas utilisé). Dans le sens inverse (utiliser une DLL COM 32 bits depuis une application 64 bits), le mécanisme est identique : la bitness du surrogate qui est lancé est déterminée par la DLL et non par le client. Cela dit, si ce que l’on veut appeler n’est qu’une simple DLL native, comme dans cet article, il n’existe dès le départ aucun serveur COM à charger dans le surrogate, et la méthode du serveur EXE décrite dans la suite reste nécessaire. La procédure d’enregistrement est résumée en 3.5 de Pièges d’enregistrement et de bitness dans le développement COM/OCX/ActiveX (cet article-là part d’une DLL 32 bits, il suffit donc d’y transposer la vue dans laquelle la valeur AppID est écrite), et la limite entre se contenter du surrogate et écrire son propre EXE est résumée en 5.2 de Comment traiter ActiveX / OCX aujourd’hui - Tableau de décision conserver / envelopper / remplacer.

3. Déroulement du traitement (diagramme de séquence)

Voici le déroulement lorsque l’application 32 bits invoque un traitement de la DLL 64 bits.

Pris en charge par l'infrastructure de marshaling COM enregistréeDLL 64bitServeur COM 64bit(EXE)COM Stub(côté 64bit)RPC/IPC(communication inter-processus)COM Proxy(côté 32bit)Application cliente 32bitDLL 64bitServeur COM 64bit(EXE)COM Stub(côté 64bit)RPC/IPC(communication inter-processus)COM Proxy(côté 32bit)Application cliente 32bitMarshaling des paramètresDémarshaling des paramètresMarshaling de la valeur de retourDémarshaling de la valeur de retourICalcService.Add(1, 2)Données sérialiséesTransfert au-delà de la frontière de processusAdd(1, 2)Appel de fonction nativeRésultat : 3Résultat : 3Résultat sérialiséTransfert au-delà de la frontière de processusRésultat : 3

Points clés :

  • L’application 32 bits peut effectuer des appels typés via l’interface ICalcService
  • Le runtime COM franchit la frontière entre processus en utilisant la DLL proxy/stub enregistrée, le marshaleur TypeLib, le marshaleur standard, etc.
  • En raison de la surcharge de la communication inter-processus, regrouper le travail est préférable à de nombreux appels fins

4. Exemple de code (conceptuel)

Ce qui suit est une esquisse conceptuelle. En pratique, l’enregistrement et la génération de la TypeLib sont également nécessaires.

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

// COM LocalServer 64bit (côté EXE)
[ComVisible(true)]
[Guid("1C9B6F4D-1E9A-4E61-9A4F-6A0F1D2D9A11")]
[ClassInterface(ClassInterfaceType.None)]
public class CalcService : ICalcService
{
    public int Add(int a, int b)
    {
        // Appeler la DLL 64bit ici
        return a + b;
    }
}

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

Sous cette forme, le côté 32 bits peut travailler « de façon typée ». COM utilise des proxies/stubs en interne et effectue l’appel via IPC pour vous.

5. Exemple de code complet

Une implémentation fonctionnelle du concept ci-dessus est publiée sur GitHub.

Call64bitDLLFrom32bitProc - GitHub

Le dépôt contient les éléments suivants :

  • Call64bitDLLFrom32bitProc/ - COM LocalServer 64bit (EXE)
  • X64DLL/ - DLL 64bit (le traitement réel)
  • X86App/ - Client 32bit (WinForms)
  • scripts/ - Scripts d’enregistrement/désenregistrement du serveur COM

Si vous le compilez et l’enregistrez en suivant les étapes du README, vous pouvez observer un processus 32 bits appelant réellement une DLL 64 bits.

6. Références

  • Vue d’ensemble du Component Object Model (COM) https://learn.microsoft.com/en-us/windows/win32/com/component-object-model–com–portal
  • Enregistrement de COM LocalServer32 https://learn.microsoft.com/en-us/windows/win32/com/localserver32
  • Notions de base sur les interfaces COM https://learn.microsoft.com/en-us/windows/win32/com/the-component-object-model
  • COM Interop (utilisation depuis .NET) https://learn.microsoft.com/en-us/dotnet/standard/native-interop/cominterop

Articles récents partageant les mêmes étiquettes, pour approfondir des sujets proches.

Ces pages replacent le sujet dans un contexte plus large de services et de décisions.

Cet article est directement lié aux services suivants.

Questions fréquentes

Questions souvent posées lors d’une consultation sur le sujet de cet article.

Une application 32 bits peut-elle charger une DLL 64 bits ?
Non. Un processus 32 bits ne peut pas charger une DLL 64 bits - il s'agit d'une contrainte au niveau du système d'exploitation Windows, pas d'un problème que l'on peut contourner par une astuce quelconque. La voie in-process est fermée dès le départ. Si vous avez besoin d'une fonctionnalité qui réside dans une DLL 64 bits, ce traitement doit s'exécuter dans un processus 64 bits séparé, et un pont COM est un moyen éprouvé de relier les deux.
Comment un pont COM relie-t-il une application 32 bits à une DLL 64 bits ?
Vous construisez un COM LocalServer 64 bits (un EXE) qui appelle la DLL 64 bits en interne, vous partagez l'interface COM via IDL ou une bibliothèque de types (TypeLib) pour exposer les types, et l'application 32 bits l'appelle via COM. Le runtime COM franchit la frontière entre processus grâce aux proxies, aux stubs et au marshaling, ce qui permet au côté 32 bits d'effectuer des appels typés via l'interface partagée.
Quels sont les principaux points d'attention avec un pont COM out-of-process ?
Il y en a trois principaux. Premièrement, les enregistrements COM 32 bits et 64 bits sont distincts, y compris la zone de registre WOW6432Node. Deuxièmement, les structures personnalisées nécessitent une conception de marshaling plutôt qu'un fonctionnement automatique. Troisièmement, la communication inter-processus ajoute une surcharge à chaque appel, il est donc préférable de regrouper le travail plutôt que de multiplier les appels fins dans des scénarios à haute fréquence.
Existe-t-il un exemple fonctionnel de pont COM 32 bits vers 64 bits ?
Oui. Une implémentation complète et fonctionnelle est publiée sur GitHub sous le nom du dépôt Call64bitDLLFrom32bitProc. Il contient un COM LocalServer EXE 64 bits, une DLL 64 bits avec le traitement réel, un client WinForms 32 bits, ainsi que des scripts d'enregistrement. Si vous le compilez et l'enregistrez en suivant le README, vous pouvez observer un processus 32 bits appelant réellement une DLL 64 bits.

Profil de l’auteur

Page de présentation de l’auteur de l’article.

Go Komura

Représentant de KomuraSoft LLC

Spécialisé dans le développement de logiciels Windows, le conseil technique et l’analyse de pannes, notamment pour les systèmes existants et les incidents difficiles à reproduire.

Retour au blog