C# 编译器如何检测 COM 类型? [英] How does the C# compiler detect COM types?

查看:25
本文介绍了C# 编译器如何检测 COM 类型?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已将结果写成 博文.

<小时>

C# 编译器有点神奇地处理 COM 类型.比如这个语句看起来很正常...

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

... 直到您意识到 Application 是一个接口.在接口上调用构造函数?哎呀!这实际上被转换为对 Type.GetTypeFromCLSID() 和另一个Activator.CreateInstance.

另外,在C#4中,你可以对ref参数使用非ref参数,编译器只是添加了一个局部变量来通过引用传递,丢弃结果:

//FileName 参数*真的*是一个引用参数app.ActiveDocument.SaveAs(文件名:test.doc");

(是的,缺少一堆参数.可选参数不是很好吗?:)

我正在尝试调查编译器的行为,但我没有伪造第一部分.我可以毫无问题地完成第二部分:

使用系统;使用 System.Runtime.InteropServices;使用 System.Runtime.CompilerServices;[ComImport, GuidAttribute("00012345-0000-0000-0000-000000000011")]公共接口 Dummy{void Foo(ref int x);}课堂测试{静态无效主(){虚拟虚拟 = 空;dummy.Foo(10);}}

我希望能够写:

Dummy dummy = new Dummy();

虽然.显然它会在执行时爆炸,但没关系.我只是在试验.

编译器为链接的 COM PIA(CompilerGeneratedTypeIdentifier)添加的其他属性似乎不起作用……有什么神奇之处?

解决方案

我绝不是这方面的专家,但我最近偶然发现了我认为您想要的东西:CoClass 属性类.

[System.Runtime.InteropServices.CoClass(typeof(Test))]公共接口 Dummy { }

<块引用>

一个coclass提供混凝土一个或多个的实现接口.在 COM 中,这种具体的实现可以写成任何支持 COM 的编程语言组件开发,例如德尔福,C++、Visual Basic 等

参见 我对有关 Microsoft Speech API 的类似问题的回答,您可以在其中实例化"接口 SpVoice(但实际上,您正在实例化 SPVoiceClass>).

[CoClass(typeof(SpVoiceClass))]公共接口 SpVoice : ISpeechVoice, _ISpeechVoiceEvents_Event { }

EDIT: I've written the results up as a blog post.


The C# compiler treats COM types somewhat magically. For instance, this statement looks normal...

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

... until you realise that Application is an interface. Calling a constructor on an interface? Yoiks! This actually gets translated into a call to Type.GetTypeFromCLSID() and another to Activator.CreateInstance.

Additionally, in C# 4, you can use non-ref arguments for ref parameters, and the compiler just adds a local variable to pass by reference, discarding the results:

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

(Yeah, there are a bunch of arguments missing. Aren't optional parameters nice? :)

I'm trying to investigate the compiler behaviour, and I'm failing to fake the first part. I can do the second part with no problem:

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);
    }
}

I'd like to be able to write:

Dummy dummy = new Dummy();

though. Obviously it'll go bang at execution time, but that's okay. I'm just experimenting.

The other attributes added by the compiler for linked COM PIAs (CompilerGenerated and TypeIdentifier) don't seem to do the trick... what's the magic sauce?

解决方案

By no means am I an expert in this, but I stumbled recently on what I think you want: the CoClass attribute class.

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

A coclass supplies concrete implementation(s) of one or more interfaces. In COM, such concrete implementations can be written in any programming language that supports COM component development, e.g. Delphi, C++, Visual Basic, etc.

See my answer to a similar question about the Microsoft Speech API, where you're able to "instantiate" the interface SpVoice (but really, you're instantiating SPVoiceClass).

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

这篇关于C# 编译器如何检测 COM 类型?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆