更新履歴(5件・最終更新 2026年08月02日)
この記事に加えた変更の記録です。アーカイブした更新前のバージョンは、DOI付きの固定URLから読めます。
- 記事の冒頭に「この記事の知識マップ」節を追加しました。本文で扱っている概念とその関係を、要約・図・詳細ページへのリンクにまとめたものです。本文の主張は変えていません。
- 外部レビュー(1283件)への対応として本文を更新しました。個々の変更内容は、この下の履歴を参照してください。
- `LocalServer32`に実行ファイルのパスを引用符なしで格納していたのを直しました。`/d "%SERVER%"`と書くと引用符は`reg.exe`の引数解析で消えるため、`C:\Program Files\...`は「`C:\Program`に`Files\...`を渡す」とも解釈でき、`C:\Program.exe`を置ける環境ではそちらが起動され得ます。引用符ごと格納する形にし、確認用の`reg query`も添えました。
- 冒頭に対象読者と前提環境を追加し、レジストリ登録の手順を新設しました(必要な3キーの表、`reg add /reg:64`と`/reg:32`による登録と解除、EXE側でのクラスファクトリ登録、管理者権限なしでHKCUに登録する代替)。ProgIDが何のためにあるかの説明、用語ミニ辞書、.NET Frameworkと.NET 5以降の差の対比表、まとめの章を追加しました。
- サンプルコードのクライアントが ProgID でサーバーを取得しているのに、サーバー側に ProgID を指定する属性が書かれておらず、そのままでは再現できませんでした。属性を補いました。
- 初版公開
この記事を引用する(DOI: 10.5281/zenodo.21589580)
この記事はZenodoにアーカイブされています。常に最新版へ解決されるDOIと、いま表示している版に固定されたDOIの両方を下に示します。
小村 豪(2026)「32bitアプリから64bit DLLを呼ぶCOMブリッジ実例」合同会社小村ソフト. https://doi.org/10.5281/zenodo.21589580 https://staging.comcomponent.com/blog/2026/01/25/002-com-case-study-32bit-to-64bit/
- DOI(最新版)
- 10.5281/zenodo.21589580
- DOI(この版)
- 10.5281/zenodo.21732574
32bit アプリから 64bit DLL を呼び出したい、という要件は Windows ではかなり典型的です。 特に既存資産を残したまま 64bit 側の機能だけ使いたいとき、COM ブリッジの構成が現実的な解になりやすいです。
対象読者: 32bit の既存 Windows アプリを保守していて、64bit 側の DLL やライブラリを使いたい方。COM を「聞いたことはあるが自分で組んだことはない」程度の前提で読めるように書いています。
前提環境: 64bit 版の Windows(x64)と、C# を書ける開発環境(Visual Studio など)。COM サーバーをマシン全体(HKEY_LOCAL_MACHINE 配下)に登録する作業には管理者権限が必要です。COM の基本的な考え方は「COM とは何か - Windows COM の設計が今でも美しい理由」で整理しています。
目次
この記事の知識マップ
32bitアプリはビット構成が一致しないin-proc COMとして64bit DLLを直接ロードできないため、この記事では64bit側の処理をCOM LocalServer(EXEサーバー)として別プロセスに分離し、IDLとTypeLibで共有したCOMインターフェース越しに型付きで呼び出します。マーシャリングとProxy/Stubがプロセス境界をまたぐ呼び出しを橋渡しし、CLSIDとProgIDの登録、そしてCLSIDサブキーが32bit viewと64bit viewで別になるWOW64レジストリリダイレクターへの両面登録が前提になります。マシン全体への登録には管理者権限が必要で、.NET(5以降)は標準のEnableComHostingがin-proc専用のためOut-of-procサーバーの登録処理は自前で書く必要があります。
flowchart LR
accTitle: 32bit/64bit COMブリッジの知識マップ
accDescr: 32bitアプリが64bit DLLをCOM LocalServerのEXEサーバーとして呼び出す構成が、型ライブラリ・マーシャリング・CLSID/ProgIDの登録・WOW64レジストリリダイレクターとどう関係するかを示す図
com_bridge_32_64["32bit/64bit COMブリッジ"]
com_localserver["COM LocalServer(別プロセスCOMサーバー)"]
type_library["型ライブラリ(TLB)"]
com_marshaling["マーシャリング"]
proxy_stub["Proxy/Stub"]
in_proc_com["In-proc COM(DLLサーバー)"]
bitness_match_requirement["bitness一致要件"]
clsid["CLSID(Class ID)"]
progid["ProgID(Programmatic Identifier)"]
wow64_registry_redirector["WOW64レジストリリダイレクター"]
wow6432node["WOW6432Node"]
reg_exe["reg.exe(/reg:32 /reg:64)"]
class_factory_registration["クラスファクトリの登録"]
admin_rights["管理者権限"]
regasm["Regasm.exe"]
dotnet[".NET(Core以降)"]
dotnet_framework[".NET Framework"]
dotnet_comhost[".NET(5以降)のEnableComHosting/.comhost.dll"]
com["COM(コンポーネントオブジェクトモデル)"]
com_bridge_32_64 -->|"利用する"| com_localserver
com_bridge_32_64 -->|"前提とする"| type_library
com_localserver -->|"利用する"| com_marshaling
com_marshaling -->|"利用する"| proxy_stub
in_proc_com -->|"前提とする"| bitness_match_requirement
com_localserver -->|"軽減する"| bitness_match_requirement
com_localserver -->|"前提とする"| clsid
progid -->|"前提とする"| clsid
com_localserver -.->|"前提とする"| wow64_registry_redirector
clsid -.->|"に保存される"| wow6432node
wow64_registry_redirector -->|"で構成できる"| reg_exe
com_localserver -->|"前提とする"| class_factory_registration
com_bridge_32_64 -.->|"前提とする"| admin_rights
regasm -->|"用いるのは非推奨"| dotnet
regasm -->|"前提とする"| dotnet_framework
dotnet_comhost -->|"利用する"| dotnet
dotnet_comhost -->|"用いるのは非推奨"| com_bridge_32_64
dotnet -.->|"前提とする"| clsid
com -.->|"利用する"| type_library
図の実線は常に成り立つ関係、破線は条件付きの関係です(成立条件は詳細ページの各関係の説明に記載)。関係すべての一覧(全19件、根拠・確度つき)と主要概念の定義は知識マップ詳細ページにまとめています。データ: JSON-LD / Turtle
1. 想定状況
32bitの既存アプリはそのままに、64bit DLLの処理を使いたいというケースです。 ところが、32bitプロセスは64bit DLLを読み込めません。これはOSレベルの制約で、工夫すればどうにかなるという話ではありません。
よくあるのは、こんな状況です。
- 既存の32bitアプリは資産として大きく、すぐには移行できない
- 64bit DLL側に新機能がある、または依存ライブラリが64bitのみ
- 32bit側から「型付きで」呼び出したい
この組み合わせでは、同一プロセス内で呼び出す道は最初から閉ざされています。
2. 解決方法
この章から専門用語が続くので、先に最小限の言葉を並べておきます。
| 用語 | 意味 |
|---|---|
| In-proc COM(DLLサーバー) | COMコンポーネントを呼び出し側と同じプロセスに読み込んで使う形。速いがビット数が一致していないと読み込めない |
| Out-of-proc COM(EXEサーバー) | COMコンポーネントを別プロセスとして起動して使う形。ビット数が違っても連携できる |
| LocalServer | 同じPC内の別プロセスとして動くCOMサーバーのこと。レジストリの LocalServer32 キーにEXEのパスを登録する |
| IDL / TypeLib | インターフェースの形(メソッド名・引数の型)を書いた定義(IDL)と、それをバイナリ化したもの(TypeLib)。両側が同じ「契約」を見るために使う |
| マーシャリング | プロセス境界を越えるために、引数や戻り値を送れる形に詰め直すこと。逆はアンマーシャリング |
| Proxy / Stub | マーシャリングを実際に行う代理コード。呼び出し側にProxy、サーバー側にStubが立つ |
| WOW6432Node | 64bit Windows 上で、32bit アプリ向けのレジストリ内容が物理的に置かれる場所。同じキー名でも32bit側と64bit側で中身が別になる |
解決の基本は、Out-of-proc COM(EXEサーバー)で分離することです。 64bit DLLは64bitのCOMサーバー(EXE)から呼び出し、32bitアプリはCOM経由で使います。
流れは次の通りです。
- 64bitのCOM LocalServer(EXE)を用意し、内部で64bit DLLを呼び出す
- COMインターフェース(IDL/TypeLib)を共有し、型を公開する
- 32bitアプリはCOMを「型付き」で呼び出す(Proxy/Marshalでやり取り)
ただし注意点もあります。
- 32bit/64bitの登録は別(WOW6432Node含む)
- 独自構造体はマーシャリング設計が必要
- IPCのオーバーヘッドがあるため、高頻度呼び出しは注意
つまり、「64bitの処理を別プロセスに逃がして、COMで橋渡しする」のが王道です。
3. 処理の流れ(シーケンス図)
以下は、32bitアプリが64bit DLLの処理を呼び出すときの流れです。
sequenceDiagram
participant App as 32bit クライアントアプリ
box rgba(100,100,255,0.1) 登録済みのCOMマーシャリング基盤が処理
participant Proxy as COM Proxy<br/>(32bit側)
participant RPC as RPC/IPC<br/>(プロセス間通信)
participant Stub as COM Stub<br/>(64bit側)
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: パラメータをマーシャリング
Proxy->>RPC: シリアライズされたデータ
RPC->>Stub: プロセス境界を越えて転送
Note over Stub: パラメータをアンマーシャリング
end
Stub->>Server: Add(1, 2)
Server->>DLL: ネイティブ関数呼び出し
DLL-->>Server: 結果: 3
Server-->>Stub: 結果: 3
rect rgba(100,100,255,0.1)
Note over Stub: 戻り値をマーシャリング
Stub-->>RPC: シリアライズされた結果
RPC-->>Proxy: プロセス境界を越えて転送
Note over Proxy: 戻り値をアンマーシャリング
end
Proxy-->>App: 結果: 3
ポイント:
- 32bitアプリは
ICalcServiceインターフェースを通じて型安全に呼び出せる - COMランタイムは、登録済みの Proxy/Stub DLL、TypeLib マーシャラー、標準マーシャラーなどを使ってプロセス境界を越える
- プロセス間通信のオーバーヘッドがあるため、細かい呼び出しより一括処理が望ましい
4. サンプルコード(イメージ)
4.1. 共有インターフェースとサーバー・クライアント
以下は概念のイメージです。動かすには、このあと 4.2 の登録が必要です。
// 共有インターフェース(IDL相当)
[ComVisible(true)]
[Guid("7A4B5B23-0A2F-4D2B-9D4D-8A2A92B8B001")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface ICalcService
{
int Add(int a, int b);
}
// 64bit COM LocalServer(EXE側)
[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)
{
// ここで64bit DLLを呼び出す
return a + b;
}
}
// 32bitアプリ側(クライアント)
Type t = Type.GetTypeFromProgID("KomuraSoft.CalcService");
var calc = (ICalcService)Activator.CreateInstance(t);
int result = calc.Add(1, 2);
この形にすると、32bit側は「型付きで」扱えます。 COMが内部でプロキシ/スタブを使い、IPC経由で呼び出してくれます。
[ProgId("KomuraSoft.CalcService")] を付けているのは、クライアント側が Type.GetTypeFromProgID("KomuraSoft.CalcService") で探せるようにするためです。ProgID は「人間が読める別名」にすぎず、実際にサーバーを見つけるのは次に説明する CLSID の登録です。
4.2. 最低限の登録手順
COMは「レジストリに登録されているCLSIDを、COMランタイムが引いて起動する」仕組みなので、登録していないコードは絶対に動きません(Type.GetTypeFromProgID が null を返すか、CreateInstance で REGDB_E_CLASSNOTREG になります)。EXEサーバー(LocalServer)に必要な登録は、突き詰めると次の3つのキーだけです。
| 登録するもの | キー | 値 |
|---|---|---|
| ProgID → CLSID の対応 | HKEY_CLASSES_ROOT\KomuraSoft.CalcService\CLSID |
{1C9B6F4D-1E9A-4E61-9A4F-6A0F1D2D9A11} |
| CLSID → EXEのパス | HKEY_CLASSES_ROOT\CLSID\{1C9B6F4D-…}\LocalServer32 |
64bit COMサーバーEXEのフルパス |
| CLSID → ProgID の逆引き | HKEY_CLASSES_ROOT\CLSID\{1C9B6F4D-…}\ProgID |
KomuraSoft.CalcService |
ここでこの記事の主題そのものの落とし穴があります。HKEY_LOCAL_MACHINE\SOFTWARE\Classes は32bitアプリと64bitアプリで共有されるのに対し、その配下の CLSID サブキー(および Interface など)は32bit側と64bit側で別々(32bit側の実体が WOW6432Node)と、Microsoft のドキュメントに明記されています。つまり ProgID のキーは一度書けば両方から見えますが、CLSID の登録は32bitビューと64bitビューの両方に書かないと、32bitクライアントからサーバーが見つかりません。
管理者権限のコマンドプロンプトで、reg コマンドの /reg:32 /reg:64 を使うのが確実です(Wow6432Node を自分でパスに書くのは、Microsoft が非推奨としています)。
:: 管理者権限のコマンドプロンプトで実行する
set CLSID={1C9B6F4D-1E9A-4E61-9A4F-6A0F1D2D9A11}
set PROGID=KomuraSoft.CalcService
set SERVER=C:\Program Files\KomuraSoft\CalcServer.exe
:: 1) ProgID → CLSID(HKLM\SOFTWARE\Classes 直下は32/64で共有)
reg add "HKLM\SOFTWARE\Classes\%PROGID%\CLSID" /ve /d "%CLSID%" /f
:: 2) CLSID → LocalServer32 と ProgID(CLSID配下は32/64で別なので両方に書く)
:: LocalServer32 の値には、実行ファイルのパスを引用符ごと入れる。
:: /d "%SERVER%" と書くと引用符は reg.exe の引数解析で消え、値は
:: C:\Program Files\... のまま格納される。COM はこれをコマンドラインとして
:: 解釈するため、空白の手前で切れた C:\Program.exe を先に探しに行く
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
:: 格納された値を確認する。"C:\Program Files\..." と引用符付きで出れば正しい
reg query "HKLM\SOFTWARE\Classes\CLSID\%CLSID%\LocalServer32" /ve /reg:64
LocalServer32 の引用符は、単に行儀の問題ではありません。引用符が無いと、C:\Program Files\... は「C:\Program に Files\... を引数として渡す」という解釈が成り立ってしまいます。その結果、C:\Program.exe を作れる権限を持つ相手がいる環境では、そちらが先に起動され得ます。空白を含むパスへ入れるなら必ず引用符を付けてください。
解除は同じキーを消すだけです。
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
加えて、EXE側は起動したときに「自分がこのCLSIDの担当だ」とCOMに名乗り出る必要があります。C/C++なら CoRegisterClassObject、.NET Framework なら RegistrationServices.RegisterTypeForComClients がこれにあたります。レジストリ登録はCOMがEXEを起動するところまでしか面倒を見てくれないので、この名乗りが抜けているとEXEは起動するのにオブジェクトが作れない、という分かりにくい失敗になります。
なお、開発中に試すだけなら HKLM の代わりに HKCU\SOFTWARE\Classes へ同じ構造で書けば管理者権限なしでも登録できます(HKEY_CLASSES_ROOT は HKLM と HKCU の合成ビューです)。ただし HKCU\SOFTWARE\Classes\CLSID も同じく32bit/64bitで別扱いなので、両方のビューに書く点は変わりません。
4.3. .NET Framework と .NET(5以降)で作り方が違う
上のコードはC#ですが、どちらの.NETを使うかで手順が大きく変わります。ここを混ぜると詰まります。
| .NET Framework | .NET(Core 3.0 / 5以降) | |
|---|---|---|
| 登録ツール | RegAsm.exe がある(ただし作られるのは in-proc 用の InprocServer32 登録なので、LocalServer32 は結局自分で書く) |
RegAsm 相当のツールはない |
| 標準的なCOM公開 | アセンブリに属性を付けて RegAsm |
<EnableComHosting>true</EnableComHosting> で *.comhost.dll を生成し regsvr32 で登録(in-proc のみ) |
| TypeLib(.tlb)の生成 | TlbExp / RegAsm /tlb で生成できる |
サポートされない。IDLを手で書いて MIDL でコンパイルする(.NET 6以降は、できあがった .tlb をcomhostに埋め込むことは可能) |
| CLSIDの指定 | 省略可 | COMから生成させるクラスには CLSID の明示が必須 |
| AnyCPU の扱い | 32bit/64bit 両方のクライアントから使える | 付随する *.comhost.dll が既定で64bitなので、64bitクライアントからしか使えない |
本記事の構成(EXEサーバー)は、.NET(5以降)では標準の EnableComHosting の範囲外なので、登録処理を自分で書くことになります。Microsoft公式のサンプルとして OutOfProcCOM が用意されているので、.NET 側で組む場合はそちらが出発点になります。
5. 完全なサンプルコード
上記の概念を実際に動作する形で実装したサンプルを GitHub で公開しています。
Call64bitDLLFrom32bitProc - GitHub
このリポジトリには以下が含まれています:
- Call64bitDLLFrom32bitProc/ - 64bit COM LocalServer (EXE)
- X64DLL/ - 64bit DLL(実処理)
- X86App/ - 32bit クライアント (WinForms)
- scripts/ - COM サーバー登録・解除スクリプト
README に記載の手順に従ってビルド・登録すれば、実際に 32bit プロセスから 64bit DLL を呼び出す動作を確認できます。
6. まとめ
COMブリッジは万能ではなく、向く仕事と向かない仕事がはっきり分かれる構成です。採用を決める前に、次の表で自分のケースを当てはめてみてください。
| 向いているケース | 向かないケース |
|---|---|
| 32bitアプリ本体を作り直せない(改修コストが見合わない) | そもそも32bit側を64bitに再ビルドできる(それが最短) |
| 呼び出しが粗い粒度(1回で画像1枚、1回でファイル1本など) | 1要素ずつ数万回など、細かい呼び出しを高頻度で回す(IPCのオーバーヘッドが支配的になる) |
| やり取りするのが数値・文字列・配列など、マーシャリングしやすい型 | 生ポインターや複雑な独自構造体を大量に往復させる |
| 64bit側の処理が落ちても、アプリ本体は生かしておきたい(プロセス分離が利点になる) | サーバー側のクラッシュや再起動を扱う復旧処理を書きたくない |
| 型付きの呼び出し(IntelliSenseやコンパイル時チェック)を残したい | 単発のバッチ処理で済み、標準入出力やファイル経由の受け渡しで十分 |
最後の行の裏返しとして、「64bit側の処理を単なるコンソールEXEにして、引数とファイルでやり取りする」という素朴な代替案も常に検討する価値があります。COMブリッジが効くのは、型付きの呼び出しを維持したい場合と、状態を持ったサーバーを何度も呼びたい場合です。
次のアクションとしては、この順番をおすすめします。
- まず 5章のサンプルリポジトリを clone して、README のとおりにビルド・登録し、動く状態を1つ手元に作る。
- 自分の 64bit DLL の関数を1つだけ選び、サンプルの
ICalcServiceに相当するインターフェースにメソッドを1本足して通す。 - 通ったら、呼び出し回数と1回あたりのデータ量を測る。ここで「粗い粒度に寄せる」設計判断(複数回の呼び出しを1回にまとめる)を先に済ませておくと、後戻りが減ります。
7. 参考資料
- Component Object Model (COM) の概要 https://learn.microsoft.com/en-us/windows/win32/com/component-object-model–com–portal
- COM LocalServer32 の登録 https://learn.microsoft.com/en-us/windows/win32/com/localserver32
- COM インターフェースの基本 https://learn.microsoft.com/en-us/windows/win32/com/the-component-object-model
- COM Interop(.NETからの利用) https://learn.microsoft.com/en-us/dotnet/standard/native-interop/cominterop
- WOW64 のレジストリリダイレクター(
HKLM\SOFTWARE\Classesは共有、CLSID配下は32/64で別) https://learn.microsoft.com/en-us/windows/win32/winprog64/shared-registry-keys - .NET(Core / 5以降)のコンポーネントをCOMに公開する https://learn.microsoft.com/en-us/dotnet/core/native-interop/expose-components-to-com
関連する記事
同じタグを共有する最新の記事です。さらに近い話題で知識を深められます。
COM/OCX/ActiveX開発でハマる登録とbitnessの罠
COM、OCX、ActiveX開発でハマりやすい32bit/64bit、Visual Studio 2022、regsvr32/Regasm、管理者権限、HKCR、STA/MTAを実務目線で整理します。
Office 2024/Microsoft 365でActiveXが動かない原因と確認手順
Office 2024/Microsoft 365でActiveXが動かない時に、既定無効化、32bit/64bit、COM登録、依存DLL、IEモード、Click-to-Runログを切り分ける順番を整理します。
Arm版Windowsで業務アプリは動くのか ── x64エミュレーション(Prism)とネイティブDLL・COMの現実
「Arm版Windowsで業務アプリは動くのか」に開発者・情シス向けに答えます。x64エミュレーション(Prism)の仕組み、ドライバーなど動かない層、.NETのAnyCPUとP/Invokeの問題、Arm対応チェックリストまで整理します。
VB6アプリはいつまで動くのか ── ランタイムのサポート状況と現実的な.NET移行の進め方
VB6アプリはいつまで動くのか。ランタイムはWindows 11でも動作対象、IDEはサポート終了という現状を整理し、全面リライト・自動変換・段階移行の判断表、移行前の棚卸し、VB6と.NETの非互換までをまとめます。
Windowsアプリ 外注・受託開発を依頼する前に整理したいこと
Windowsアプリの外注・受託開発を依頼する前に、既存ソフト改修、装置連携、COM/ActiveX、配布・更新、保守の整理ポイントを解説します。
関連トピック
このテーマと近いトピックページです。記事を起点に、関連するサービスや他の記事へ進めます。
Windows技術トピック
Windows 開発、不具合調査、既存資産活用の技術トピックをまとめた入口です。
ActiveX / 移行テーマ
COM / ActiveX / OCX を残すか、包むか、置き換えるかを整理するトピックです。
32bit / 64bit テーマ
32bit / 64bit、ネイティブ連携、C++/CLI まわりを整理するトピックです。
このテーマがつながるサービス
この記事は次のサービスページにつながります。近い入口からご覧ください。
既存資産活用・移行支援
32bit 資産を残しながら 64bit 側へ橋をかける話なので、既存資産活用・移行支援 に直結するテーマです。
技術相談・設計レビュー
COM ブリッジやプロセス境界の切り方を先に整理したい段階なら、技術相談・設計レビューとして比較検討できます。
よくある質問
この記事のテーマについて、相談時によくある質問をまとめています。
- 32bitアプリから64bit DLLを直接呼び出せますか?
- できません。32bitプロセスは64bit DLLを読み込めず、これはOSレベルの制約で、工夫すれば回避できるという話ではありません。同一プロセス内で呼び出す道は最初から閉ざされているため、64bit側の処理を別プロセスへ分離する構成が必要になります。
- 32bitアプリから64bit DLLの機能を使うにはどうすればよいですか?
- Out-of-proc COM(EXEサーバー)で分離するのが王道です。64bit DLLは64bitのCOM LocalServer(EXE)から呼び出し、32bitアプリはCOMインターフェース経由で型付きで利用します。COMインターフェース(IDL/TypeLib)を共有して型を公開し、COMランタイムがプロキシ/スタブとプロセス間通信で境界を越えてくれます。
- COMブリッジ構成の注意点は何ですか?
- 主に3点あります。32bit/64bitの登録は別である(WOW6432Node含む)こと、独自構造体はマーシャリング設計が必要なこと、そしてプロセス間通信のオーバーヘッドがあるため高頻度の細かい呼び出しには注意が必要なことです。細かい呼び出しを大量に流すより、一括処理に寄せるのが望ましいです。
- 実際に動作するサンプルコードはありますか?
- あります。GitHubのCall64bitDLLFrom32bitProcリポジトリに、64bit COM LocalServer(EXE)、64bit DLL、32bitクライアント(WinForms)、COMサーバー登録・解除スクリプトを含むサンプル一式が公開されています。READMEの手順に従ってビルド・登録すれば、32bitプロセスから64bit DLLを呼び出す動作を確認できます。