简体   繁体   English

C#COM与C ++ COM返回值

[英]C# COM vs C++ COM return value

I'm building a COM component C#, the customer can set binary data. 我正在构建一个COM组件C#,客户可以设置二进制数据。 It would be nice if the COM component returns exception rather than error code, but realized it would be difficult to handle exception in (Delphi, C + + and JScritp). 如果COM组件返回异常而不是错误代码,那将是很好的选择,但是意识到(Delphi,C ++和JScritp)将很难处理异常。 I chose it receives a data in hexadecimal (internally convert to binary) and return in hexadecimal (internally convert binary to hexadecimal). 我选择接收十六进制的数据(内部转换为二进制)并返回十六进制的数据(内部将二进制转换为十六进制)。
The method getData can return the data and a error code, the question is: how to do this in C# interop? 方法getData可以返回数据和错误代码,问题是:如何在C#互操作中执行此操作?

in C++ COM exists the HRESULT 在C ++ COM中存在HRESULT

HRESULT getData([in] int __position, [out,retval] BSTR* __data); // can Return __data or error -1 data not exists
HRESULT setData([in] BSTR __data, [out,retval] int* __status);

but in C# COM ?? 但是在C#COM中??

int getData ??? // return __status or __data;
int setData(String __data); // return __status;

thanks in advanced, 提前致谢,

C# maps known C# exceptions to HRESULT values. C#将已知的C#异常映射到HRESULT值。 Here is Microsoft's documentation on the mapping list. 是有关映射列表的Microsoft文档。 You can get further control by throwing a COMException . 您可以通过引发COMException获得进一步的控制。

Just throw an exception in C#. 只需在C#中引发异常即可。 The C# interop layer will know how to catch the exception, return a E_FAIL hresult (or other appropriate value if the C# exception is known or a COMException that specifies the value explicitly) and setup the IErrorInfo on your COM object. C#互操作层将知道如何捕获该异常,返回E_FAIL hresult(如果已知C#异常或显式地指定该值的COMException ,则返回其他适当的值),并在COM对象上设置IErrorInfo The C++ smart COM pointers like _com_ptr_t know how to handle this case and will raise an appropriate C++ exception. _com_ptr_t这样的C ++智能COM指针知道如何处理这种情况,并将引发适当的C ++异常。

See Handling COM Interop Exceptions . 请参阅处理COM互操作异常

You should return an HRESULT from each COM method and return the data in out parameters. 您应该从每个COM方法返回一个HRESULT并返回out参数中的数据。 However, the COM interop layer shields this from you by automatically translating between COM HRESULT error codes and C# exceptions. 但是,COM互操作层通过自动在COM HRESULT错误代码和C#异常之间进行转换来屏蔽您。 I think your code should really look like this: 我认为您的代码应该看起来像这样:

MIDL MIDL

HRESULT getData([out,retval] BSTR* pData);
HRESULT setData([in] BSTR data);

C# C#

String getData();
void setData(String data);

The key point is that the COM function return value is always an HRESULT . 关键是COM函数的返回值始终是HRESULT If the function succeeds then S_OK is returned—otherwise you an appropriate error code that describes the reason for failure is returned. 如果函数成功,则返回S_OK否则,您将返回描述失败原因的适当错误代码。 The true return value, data in this example, is returned through an out parameter rather than the return value. 真正的返回值(在此示例中为data是通过out参数而不是返回值返回的。 But of course, the COM interop layer hides that implementation detail from you. 但是,当然,COM互操作层对您隐藏了该实现细节。

Your question appears to suggest that you wish for the return value to be either an HRESULT in case of failure, or a string in case of success. 您的问题似乎表明您希望返回值在失败的情况下为HRESULT ,在成功的情况下为字符串。 This is not possible since function return values are statically typed. 这是不可能的,因为函数返回值是静态类型的。

This should work: 这应该工作:

[DllImport(DllName)]
static extern int getData(int __position, StringBuilder __data);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM