在C#程序中,我实现了以下功能:
int Test();
在程序的本机部分(用C ++编写)中定义如下:
HRESULT Test();
或可能:
DWORD Test();
因此,在实现函数时,我需要从C#部分返回HRESULT和其他标准Windows代码。此时我已按如下方式实施:
public int Test()
{
return 0x00000102; // WAIT_TIMEOUT
}
问题如何在C#中使用人类可读的代码?我想写一些像return WAIT_TIMEOUT;
这样的东西,就像我在C ++中做的那样。
我正在寻找一个不需要下载外部库或类似内容的解决方案。只有标准的.NET。
顺便说一句WAIT_TIMEOUT
不是HRESULT
,但我希望你能理解这个问题 - 问题不是关于特殊情况,而是关于标准Windows常量。我只是尝试在C#(E_NOTIMPL
,WAIT_OBJECT_0
,S_FALSE
等中使用标准Windows定义。)
答案 0 :(得分:3)
return 0x00000102; // WAIT_TIMEOUT
您需要从修复代码开始,这不是一个合适的HRESULT。它们具有高位设置以指示遇到错误条件。现在,您的C ++代码将假定您的C#方法没有失败,通常使用SUCCEEDED()或FAILED()宏来完成。
看看WinError.h SDK包含文件。它记录了HRESULT的结构,并定义了众所周知的winapi错误代码和HRESULT。它还有一个HRESULT_FROM_WIN32()的定义,这是一个帮助宏,它将win32错误代码打包到适当的HRESULT中。
您可以在C#代码中执行相同操作:
static class Win32Interop {
const int WAIT_TIMEOUT = 0x102;
static void ThrowWin32Error(int err) {
unchecked {
int hr = (int)0x80070000 + err;
System.Runtime.InteropServices.Marshal.ThrowExceptionForHR(hr);
}
}
}
现在你可以写:
public void test() {
ThrowWin32Error(WAIT_TIMEOUT);
}
以这种看似精细的方式执行此操作可确保异常具有合理描述的Message属性,并且您可以在C ++代码中提供超出stark HRESULT值的更丰富的错误信息。使用IErrorInfo接口执行此操作。另请注意,许多内置的.NET异常已经具有正确的HResult值。所以简单地抛出异常就足够了。发现并非易事,您必须查看参考源。
请记住,使用win32函数产生的实际的Win32错误代码非常容易引起误解。任何试图诊断0x80070102的人都会一直在寻找失败的操作系统调用。如果您的C#代码没有,那么接下来会非常严重。因此,我建议你这样做:
public void test() {
throw new TimeoutException();
}
在C ++代码中生成COR_E_TIMEOUT(0x80131505)。当您调用C#代码时,您需要熟悉的HRESULT类型。这些错误代码在CorError.h SDK包含文件中定义。
答案 1 :(得分:2)
我认为你正在寻找WinAPI defines for C#。不确定这是否足够,但总的来说这个网站有一些其他的定义和类似C#的东西。
答案 2 :(得分:2)
选项1:
使用枚举。您可以在此处找到一些错误代码:Common HRESULT values。
选项2:
使用VSConstants
类,错误代码已在那里定义为int常量。
选项3:
为了更符合.NET,您的公共C#方法应该抛出类似.NET的异常,而不是使用错误代码。为此,您可以使用Marshal.ThrowExceptionForHR(int)
方法,也可以根据this页面进行映射。