托管原型中的 bool 与 BOOLEAN

Jim*_*hel 3 .net c# interop

我正在尝试在 C# 中为[CreateSymbolicLink][1]API 函数创建一个托管原型。WinBase.h 中的原型是:

BOOLEAN APIENTRY CreateSymbolicLink (
    __in LPCWSTR lpSymlinkFileName,
    __in LPCWSTR lpTargetFileName,
    __in DWORD dwFlags
    );
Run Code Online (Sandbox Code Playgroud)

而 BOOLEANBYTE在 WinNT.h 中被定义为 a 。美好的。所以我的托管原型应该是:

[DllImport("kernel32.dll", SetLastError = true)]
static extern bool CreateSymbolicLink(string SymlinkFileName, string TargetFileName, UInt32 Flags);
Run Code Online (Sandbox Code Playgroud)

至少,我会这么认为。 bool只是一个别名System.Boolean,一个一字节的值。但它似乎不起作用。

我执行此代码:

bool retval = CreateSymbolicLink(LinkFilename, TargetFilename, 0);
Run Code Online (Sandbox Code Playgroud)

它返回true。但是没有创建符号链接。它没有被创建的原因是我没有以提升的权限运行。 GetLastError返回 1314,根据 WinError.h 这意味着我没有所需的权限。正如预期的那样。但为什么我的返回值是true

奇怪的是,如果我将托管原型更改为:

static extern byte CreateSymbolicLink(string SymlinkFileName, string TargetFileName, UInt32 Flags);
Run Code Online (Sandbox Code Playgroud)

和我的代码:

byte retval = CreateSymbolicLink(LinkFilename, TargetFilename, 0);
Run Code Online (Sandbox Code Playgroud)

然后我得到了预期的结果: retval包含 0,意味着函数失败。

我想我更大的问题是为什么boolBOOLEAN返回值不起作用?

Ben*_*n M 5

使用适当的MarshalAs属性标记返回值:

[DllImport("kernel32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.U1)]
static extern bool CreateSymbolicLink(string SymlinkFileName, 
    string TargetFileName, UInt32 Flags);
Run Code Online (Sandbox Code Playgroud)

从本机代码到托管代码的 bool 的默认编组是 4 个字节——您可能会true返回原始 bool,因为错误编组的堆栈字节之一是非零的。(我猜最后一部分。)