如何在C#程序中使用标准Windows定义



在C#程序中,我实现了以下函数:

int Test();

它在程序的本机部分(用C++编写(中定义如下:

HRESULT Test();

或者可能:

DWORD Test();

因此,在实现函数时,我需要从C#部分返回HRESULT和其他标准Windows代码。目前我已经实现如下:

public int Test()
{
  return 0x00000102; // WAIT_TIMEOUT
}

问题是如何使用C#中的可读代码?我想像用C++一样编写return WAIT_TIMEOUT;

我正在寻找一个不需要下载外部库或类似的解决方案。只有标准。NET。

顺便说一句,WAIT_TIMEOUT不是HRESULT,但我希望你能理解这个问题——这个问题不是关于特殊情况,而是关于标准的Windows常量。我只是想在C#中使用标准的Windows定义(E_NOTIMPLWAIT_OBJECT_0S_FALSE等(

   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++代码中提供更丰富的错误信息,而不仅仅是赤裸裸的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:

使用枚举。您可以在此处找到一些错误代码:常见的HRESULT值。

选项2:

使用VSConstants类,错误代码已经被定义为int常量。

选项3:

做得更多。NET兼容,您的公共C#方法应该抛出。NET类异常,而不是使用错误代码。为此,您可以使用Marshal.ThrowExceptionForHR(int)方法,也可以基于此页面进行一些映射。

我认为您正在寻找针对C#的WinAPI定义。不确定这是否足够,但总的来说,afair这个网站有一些其他的C#定义和类似的东西。

最新更新