DllImport ERROR_MORE_DATA UNMANAGED在C#PBYTE中调用C ++

时间:2012-05-30 17:41:15

标签: c# winapi registry unmanaged dllimport

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 - 我应该使用什么容量?
  3. 来自MSDN

      

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

2 个答案:

答案 0 :(得分:1)

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

如果你想要数据,你应该使用UIntPtr而不是IntPtr,lpData字段应该是一个字节数组。

答案 1 :(得分:0)

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

(这些不是显式用于您的api,而是也在使用PBYTE。如果将msdn中的c ++值与列出的链接进行比较)

您很可能需要定义

    var myIntPtr = Marshal.AllocCoTaskMem(sizeOfMyIntPtr);