如何在C#编译器检测到COM类型? [英] How does the C# compiler detect COM types?
问题描述
编辑:我已经写的结果成一个的博客文章。
C#编译器把COM类型有点神奇。例如,这个语句看起来正常...
Word.Application应用=新Word.Application();
...直到你意识到应用
是一个接口。调用接口的构造? Yoiks!这实际上被转换成调用<一个href=\"http://msdn.microsoft.com/en-us/library/system.type.gettypefromclsid.aspx\"><$c$c>Type.GetTypeFromCLSID()$c$c>和另一<一href=\"http://msdn.microsoft.com/en-us/library/system.activator.createinstance.aspx\"><$c$c>Activator.CreateInstance$c$c>.
此外,在C#4,可以使用非参考论据 REF
参数,编译器只是增加了一个局部变量通过引用传递,丢弃的结果:
// FileName参数是* *真正ref参数
app.ActiveDocument.SaveAs(文件名:Test.doc的);
(是啊,有一堆参数丢失不是可选参数不错:?)
我想探讨编译器的行为,我没有伪造的第一部分。我可以没有问题做第二部分:
使用系统;
使用System.Runtime.InteropServices;
使用System.Runtime.CompilerServices;[ComImport,GuidAttribute(00012345-0000-0000-0000-000000000011)]
公共接口假人
{
无效美孚(REF INT X);
}类测试
{
静态无效的主要()
{
虚拟假人= NULL;
dummy.Foo(10);
}
}
我希望能够写:
虚拟假人=新的虚拟();
虽然。显然,它会去执行时的一声,不过没关系。我只是尝试。
编译器为链接COM PIA的(编译器生成
和 TypeIdentifier
)似乎并没有添加其他属性这样的伎俩......有什么魔力酱?
绝不是我在这方面的专家,但我最近偶然什么我想你想:在<一个href=\"http://msdn.microsoft.com/en-us/library/system.runtime.interopservices.coclassattribute.aspx\">CoClass属性类。
[System.Runtime.InteropServices.CoClass(typeof运算(测试))]
公共接口虚拟{}
一个组件类供应混凝土
一个或一个以上的实施(多个)
接口。在COM中,混凝土等
实施方式可以写在任何
支持COM编程语言
组件开发,例如德尔福,
C ++,Visual Basic中,等等。
块引用>请参阅my回答有关Microsoft Speech API的类似的问题,在这里你能实例界面
SpVoice
(不过说真的,你实例化SPVoiceClass
)。[伴生类(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 toType.GetTypeFromCLSID()
and another toActivator.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
andTypeIdentifier
) 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 instantiatingSPVoiceClass
).[CoClass(typeof(SpVoiceClass))] public interface SpVoice : ISpeechVoice, _ISpeechVoiceEvents_Event { }
这篇关于如何在C#编译器检测到COM类型?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!