代码之家  ›  专栏  ›  技术社区  ›  Jim Mischel

托管原型中的布尔值与布尔值

  •  3
  • Jim Mischel  · 技术社区  · 16 年前

    我正在尝试在C中为 [CreateSymbolicLink][1] API函数。winbase.h中的原型是:

    BOOLEAN APIENTRY CreateSymbolicLink (
        __in LPCWSTR lpSymlinkFileName,
        __in LPCWSTR lpTargetFileName,
        __in DWORD dwFlags
        );
    

    布尔值定义为 BYTE 在Winnt.h.很好。所以我的管理原型应该是:

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

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

    我执行此代码:

    bool retval = CreateSymbolicLink(LinkFilename, TargetFilename, 0);
    

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

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

    static extern byte CreateSymbolicLink(string SymlinkFileName, string TargetFileName, UInt32 Flags);
    

    我的代码是:

    byte retval = CreateSymbolicLink(LinkFilename, TargetFilename, 0);
    

    然后我得到预期的结果: retval 包含0,表示函数失败。

    我想我最大的问题是为什么不 布尔 为工作 BOOLEAN 返回值?

    2 回复  |  直到 16 年前
        1
  •  4
  •   Ben M    16 年前

    用适当的 MarshalAs 属性:

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

    bool从本机代码到托管代码的默认封送为4个字节——您可能得到 true 返回原来的bool,因为错误排列的堆栈字节之一不是零。(我猜是最后一部分。)

        2
  •  1
  •   JaredPar    16 年前

    由于本机bool和托管bool之间的差异,具有布尔类型的pinvoke可能会产生意外的结果。我写了一篇关于这个主题的博客文章,详细介绍了不同类型的数据整理的区别和正确方法。

    在这种情况下,本·M有正确的答案。

    推荐文章