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

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

问题描述

编辑:我已经写的结果成一个的博客文章


C#编译器把COM类型有点神奇。例如,这个语句看起来正常...

  Word.Application应用=新Word.Application();

...直到你意识到应用是一个接口。调用接口的构造? Yoiks!这实际上被转换成调用<一个href=\"http://msdn.microsoft.com/en-us/library/system.type.gettypefromclsid.aspx\"><$c$c>Type.GetTypeFromCLSID()和另一<一href=\"http://msdn.microsoft.com/en-us/library/system.activator.createinstance.aspx\"><$c$c>Activator.CreateInstance.

此外,在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 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天全站免登陆