【问题标题】:DllImport ERROR_MORE_DATA UNMANAGED Call C++ in C# PBYTEDllImport ERROR_MORE_DATA UNMANAGED 在 C# PBYTE 中调用 C++
【发布时间】:2012-05-30 17:41:15
【问题描述】:
DWORD OREnumValue(
  __in         ORHKEY Handle,
  __in         DWORD dwIndex,
  __out        PWSTR lpValueName,
  __inout      PDWORD lpcValueName,
  __out_opt    PDWORD lpType,
  __out_opt    PBYTE lpData,
  __inout_opt  PDWORD lpcbData
);

我的代码:

public static extern uint OREnumValue(IntPtr Handle, uint dwIndex, [MarshalAsAttribute(UnmanagedType.LPWStr)] out StringBuilder lpValueName, ref int lpcValueName, out uint lpType, out IntPtr lpData, ref int lpcbData);

    IntPtr Handle=mykey;
    uint dwIndex=0;

    StringBuilder lpValueName = new StringBuilder(16383);
    int lpcValueName=lpValueName.Capacity;  

    uint lpType=0;
    IntPtr lpData;
    int lpcbData = int.MaxValue;

    uint ret3= OREnumValue(Handle, dwIndex, out lpValueName, ref lpcValueName, out lpType, out lpData, ref lpcbData);

这给出了一个错误:

ret3=ERROR_MORE_DATA 259

我认为问题出在

  1. lpData - 我应该为 PBYTE 使用什么?或者
  2. lpcbData - 我应该使用什么容量?

来自 MSDN

如果 lpData 指定的缓冲区不够大,无法容纳 数据,该函数返回 ERROR_MORE_DATA 并存储所需的 lpcbData 指向的变量中的缓冲区大小。在这种情况下, lpData 的内容未定义。

【问题讨论】:

标签: c# winapi registry unmanaged dllimport


【解决方案1】:

你永远不应该明确定义字符串构建器的长度,这个值应该使用 RegQueryInfoKey 方法获得,它将为你提供最长值名称、子键名称和值数据的字节长度,然后你可以使用它来初始化接收实际名称和数据的字符串构建器和字节数组。这意味着您使用的内存量尽可能少,同时仍然足够大以包含结果。我很确定您的问题在于您为 lpValueName 定义的长度。

此外,如果您需要数据,您应该使用 UIntPtr 而不是 IntPtr,并且 lpData 字段应该是一个字节数组。

【讨论】:

【解决方案2】:

根据以下来源,您应该将 IntPtr 用于 PBYTE:

(这些不明确用于您的 api,但也使用 PBYTE。如果您将来自 msdn 的 c++ 值与列出的链接进行比较)

你很可能需要定义

    var myIntPtr = Marshal.AllocCoTaskMem(sizeOfMyIntPtr);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-04-19
    • 1970-01-01
    • 1970-01-01
    • 2012-05-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多