dllを登録しようとしました。しかし、E:Source Code \ bin\Interop.HTML2XHTMLLib.dllがロードされました。しかし、DllRegisterServerエントリポイントが見つかりませんでした。このエラーメッセージが表示されました。なぜ?
Interop .HTML2XHTMLLib.dllファイルは、zippy32を使用して登録するライブラリではありません。これは、管理された相互運用機能アセンブリのみであり、生成されて、.NETアプリケーションがCOMオブジェクトにアクセスできるようにします。実際には、HTML2XHTMLLib.dllのタイプライブラリを登録する必要があります。
これを行うには、2つのオプションがあります。
- ライブラリを含む再配布可能なパッケージを見つけて、アプリケーションと一緒にインストールします。
- 開発システムで、VisualStudioの[参照の追加]ダイアログを開きます。[COM]タブを選択し、ライブラリを検索します(参照を追加したときと同じように)。そこにライブラリへの絶対パスがあります。ライブラリをクライアントシステムにコピーし、を使用して登録し
regsvr32
ます。
HTML2XHTMLLibのソースがわからないので、それらの方法しか提案できません。あなたは最初のものを好むべきです。
あなたはこれについて賞金を獲得し始めたので、COMとInterOpについてもう少し詳しく説明したいと思います。
COMアセンブリと.NETアセンブリの違い
COMには、InProc-serversとOutProc-serversの2種類のサーバーがあります。InProc (処理中)は、通常DLLとして認識されているサーバーです。OutProc(Out of Process)サーバーはスタンドアロンであり、独自のプロセスで実行されています。私たちはそれらをEXEカッタブルとして知っています。
InProcサーバーを使用したい。COMサーバー(HTML2XHTMLLib)は、次の2つの部分で構成されています。
- サーバーに関するメタ情報を含むタイプライブラリ(
.tlb
)、オブジェクトとそのアクセス可能性が含まれています。
- すべてのオブジェクトが実装されているコードを含むライブラリ。ライブラリは、次の静的関数もエクスポートします。
タイプライブラリはDLLまたはEXEファイルのリソースにもなるため、ファイルは1つだけです。C#開発者にとって、メタ情報は.NETアセンブリに直接コンパイルされ、リフレクションを介してアクセスできるため、これはやや混乱しているように見えます。
InterOp:.NETとCOMの間のラッパー
したがって、基本的にタイプライブラリは、COMを介して公開されたオブジェクトにアクセスするために.NETリフレクションに必要なすべてを記述します。ただし、問題は、COMコンポーネントが異なる形式で格納されていることです。
- 通常、これらはマシンコードに直接コンパイルされます。AnyCPUでコンパイルされた.NETアセンブリをCOMサーバーにリンクすることはできません。COMサーバーは、x86-アセンブラーまたはx86-64-アセンブラーのいずれかに直接コンパイルされます。それらは固定ポインタサイズを持っているため、コンパイルモデルの1つとのみ互換性があります。
- COMは、メモリ管理のルールを定義します。各COMオブジェクトは
IUnknown
-interfaceを実装する必要があります。このインターフェースは3つのメソッドを定義します。メソッドAddRef
とRelease
はメモリ管理を目的としています。クライアントがCOMオブジェクトにアクセスするときはいつでも、を呼び出す必要がありますAddRef
。これにより、カウンターが1つ増えます。クライアントがオブジェクトを必要としなくなった場合、オブジェクトを削除する代わりにクライアントが呼び出しRelease
、カウンターがデクリメントされます。ポインタが0に達すると、オブジェクトはそれ自体を削除します。これは、.NETがメモリを管理する方法とは異なります。.NETでは、ガベージコレクターは非決定論的な方法でヒープ上の各オブジェクトにアクセスし(オブジェクトが削除される正確な時点を決定することはできません)、参照が残っていない場合はオブジェクトを解放します。
- COMは、IDのルールを定義します。オブジェクトのベースインターフェイスにのみアクセスする場合は
QueryInterface
、で定義されているメソッドを呼び出す必要がありますIUnknown
。このメソッドは、特定のインターフェイスが照会されたときに、常に同じポインタを返すことが保証されています。これは.NETにも当てはまる可能性があります(一部の演算子をオーバーロードしている場合を除く)が、.NETがオブジェクトIDを保証する方法は異なります。
- COMは、オブジェクト関係のルールを定義します。AggregationやContainmentのようなクレイジーなものは、.NETにも存在しますが、実装方法が異なります。
- COMは、シングルスレッドアパートやマルチスレッドアパートなどのさまざまなマルチスレッドルールを定義します。これらのスレッドモデルは、オブジェクトがさまざまな方法で共存している場合に、オブジェクトがどのように相互作用するかを定義します。.NETでは、各同期プロセスを手動で実行する必要があります。
このリストは完全ではない可能性があります。これはあなたの質問に付随するものであるため、これ以上詳しく説明したくありませんが、.NETとCOMには大きな違いがいくつかあります。そして、これらの違いを管理するために、両方の世界の間に層があります:COMInterOp。
.NETからCOMサーバーを呼び出す場合、InterOpは.NETアセンブリにすぎず、内部ですべてのハードワークを実行します。tlbimp.exeツールを使用して作成されます。Visual Studioは通常、[COM]タブからライブラリを参照しているときはいつでもそれを呼び出します。結果は、登録したいライブラリであるInterOp.Libary.dllです。このライブラリは、COMサーバーのタイプライブラリのすべてのタイプを再定義し、COMに必要なルールを実装して、実際の呼び出しを実行します。ただし、これは、前述のメソッドを定義しないマネージド.NETライブラリです。これが、エントリポイントregsvr32
が見つからない理由です。DllRegisterServer
上記の方法は、アンマネージCOMサーバーとマネージ.NETクライアントを使用した一方向のみです。対応するtlbexp.exeと。を使用する別の方法もありregasm
ます。