1. ホーム
  2. c#

[解決済み] C#コンパイラはどのようにCOM型を検出するのですか?

2022-04-24 10:35:28

質問内容

EDITです。 として書き上げました。 ブログ記事 .


C#コンパイラは、COM型を多少魔法のように扱います。例えば、この文は普通に見えますが...

Word.Application app = new Word.Application();

...気がつくまで Application はインターフェースです。インターフェイスでコンストラクタを呼び出す?ヨイクス! これは、実際には、以下の呼び出しに変換されます。 Type.GetTypeFromCLSID() と、もうひとつは Activator.CreateInstance .

さらに、C# 4 では、非参照の引数で ref この場合、コンパイラは参照渡しのためのローカル変数を追加するだけで、結果は破棄されます。

// FileName parameter is *really* a ref parameter
app.ActiveDocument.SaveAs(FileName: "test.doc");

(ああ、引数がたくさん抜けている。オプショナルパラメーターっていいよね :)

コンパイラの挙動を調査しようとしているのですが、最初の部分のフェイクに失敗しています。2番目の部分は問題なくできるのですが。

using System;
using System.Runtime.InteropServices;
using System.Runtime.CompilerServices;

[ComImport, GuidAttribute("00012345-0000-0000-0000-000000000011")]
public interface Dummy
{
    void Foo(ref int x);
}

class Test
{
    static void Main()
    {
        Dummy dummy = null;
        dummy.Foo(10);
    }
}

書けるようになりたいです。

Dummy dummy = new Dummy();

が、しかし。もちろん、実行時にバンバン鳴りますが、それはそれでいいんです。実験中だから。

リンクされたCOM PIAのためにコンパイラが追加した他の属性( CompilerGeneratedTypeIdentifier を使ってもうまくいかないようなのですが...何かいい方法があるのでしょうか?

解決方法は?

私は決してこの分野の専門家ではありませんが、最近、あなたが望んでいると思われるものを偶然見つけました。 CoClass 属性のクラスです。

[System.Runtime.InteropServices.CoClass(typeof(Test))]
public interface Dummy { }

コクラスは具体的な を実装したもので、1つ以上の インターフェースです。COM では、このような具象 の実装は、どのようなものでも書くことができます。 COMをサポートするプログラミング言語 コンポーネント開発、例:Delphi, C++、Visual Basicなど。

参照 Microsoft Speech APIに関する同様の質問に対する私の回答です。 で、そのインターフェイスをインスタンス化することができます。 SpVoice (をインスタンス化しているのです。 SPVoiceClass ).

[CoClass(typeof(SpVoiceClass))]
public interface SpVoice : ISpeechVoice, _ISpeechVoiceEvents_Event { }