是否可以通过 COM 公开引用类型?

我有一个由 C# 制作的 dll,需要从现有的本机 C++ exe 调用它。研究了COM的基础,做了一个简单的例子。

但是,如果一个 C# 函数有一个引用类型(尤其是用户定义类的引用)参数,我可以为它编写一个接口,并且工作正常吗?

我在谷歌搜索,但得到的信息很少。

更新:
我试着写一个并看到它生成的 tlh 文件。C# 代码是

void Test2(ref float num);

生成的 tlh 是

HRESULT Test2 ( float * num );

引用类型被转换为指针类型。似乎 COM 不支持引用类型。


慕沐林林
浏览 120回答 1
1回答

红糖糍粑

正如汉斯所提到的,这个问题与引用类型无关。这是关于通过引用传递参数。当您在任何语言中通过引用传递参数时,您都显式或隐式地使用了指针。在 C# 中,ref声明“此参数将采用指向已初始化数据的指针”。out声明“此参数将采用指向可能已或可能尚未初始化的数据的指针。” 通过使用refor out,您可以屏蔽指针语义。也就是说,您不必float*在方法签名中指定。但是请放心,您仍在使用指针。COM 完全支持通过引用传递参数。这里有一个例子来说明。C#:[Guid("962232c8-90b2-4b61-8ef3-83298901c63e")][ComVisible(true)]public interface ICSCOMCLASS{    [DispId(1)]    void TestInParameter(double num);    [DispId(2)]    void TestRefParameter(ref double num);}编译后,您可以tlbexp.exe在生成的程序集上运行以导出 COM 类型库。然后,您可以通过以 .zip.tlb格式打开文件来查看 IDL oleview.exe。[    odl,    uuid(962232C8-90B2-4B61-8EF3-83298901C63E),    version(1.0),    dual,    oleautomation,    custom(0F21F359-AB84-41E8-9A78-36D110E6D2F9, "CSCOMLIB.ICSCOMCLASS")    ]interface ICSCOMCLASS : IDispatch{    [id(0x00000001)]    HRESULT TestInParameter([in] double num);    [id(0x00000002)]    HRESULT TestRefParameter([in, out] double* num);};注意参数上的修饰符。至于你关于ref参数的问题,注意TestRefParameter()方法的参数是[in, out] double* num。这相当于 C# 的ref double num.如果您使用 C/C++ 中的此程序集或类型库(例如,通过使用#import语句),您将看到如下内容:struct ICSCOMCLASS : IDispatch{    virtual HRESULT __stdcall TestInParameter(double num) = 0;    virtual HRESULT __stdcall TestRefParameter(double* num) = 0;};COM 旨在在 C 级别及更高级别上工作。大多数用于 C++ COM 工作的工具都被实现为使用 C(而不是 C++)作为它们的支持基准。尽管 C++ 支持通过引用传递&(例如HRESULT TestRefParameter(double& num),C 不支持。此外,C++&不像 C#ref和那样具体out。(大多数现代 C++ 编译器假设您希望在通过引用传递之前初始化数据,并且它们会产生一个错误或警告,如果你不)。因此,定义为任何参数ref或out在C#中的定义将被简称C ++定义为指针。
打开App,查看更多内容
随时随地看视频慕课网APP