在C#

时间:2017-03-30 11:21:52

标签: c# .net com atl stub

我的ATL项目中有这个方法,它暴露了一个COM对象(从我的*.idl文件中获取的片段):

[id(1)] HRESULT Create([in, string] CHAR* location, [out] CerberusErrorDetails* details);

注册我的对象并从我的托管C#代码添加对它的引用后,它会为此方法生成以下代理存根C#代码:

[DispId(1)]
void Create(string location, out CerberusErrorDetails details);

这个存根有一些问题,我无法理清。首先,它不会在托管代码中返回int值(相对于返回的HRESULT)来告诉我实际发生了什么错误。其次,该方法将抛出异常而不是返回错误代码。有没有办法让函数返回int,这样我就可以解析details对象,如果它没有返回0,或者有任何替代方法可以获得我想要的行为?任何帮助是极大的赞赏。如果您需要更多详细信息,请随时提出,我会更新问题。谢谢!

1 个答案:

答案 0 :(得分:2)

是的,可以绕过COM互操作层的默认异常转换行为。但是,您必须重新定义本机COM接口并使用PreserveSig属性修饰所有方法:

[ComImport]
[Guid("xxx-yyy-zzz")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
interface ICOMInterfaceImp
{
     [PreserveSig]
     int Create(string location, out CerberusErrorDetails details);
}

然后,您可以在客户端中使用此界面:

ICOMInterfaceImp obj = (ICOMInterfaceImp)new CoClassImpl();

作为替代方法,您还可以使用here中更新的类型库导入程序(tlbimp.exe)并传递/PreserveSig标记。