简体   繁体   English

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

[英]DllImport ERROR_MORE_DATA UNMANAGED Call C++ in C# PBYTE

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
);

My Code: 我的代码:

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);

This gives an error: 这给出了一个错误:

ret3=ERROR_MORE_DATA 259

I think problem is either in 我认为问题出在

  1. lpData - what should I use for PBYTE? lpData-我应该对PBYTE使用什么? Or 要么
  2. lpcbData - what capacity should I use? lpcbData-我应该使用什么容量?

From MSDN 从MSDN

If the buffer specified by lpData is not large enough to hold the data, the function returns ERROR_MORE_DATA and stores the required buffer size in the variable pointed to by lpcbData. 如果lpData指定的缓冲区不足以容纳数据,则该函数返回ERROR_MORE_DATA并将所需的缓冲区大小存储在lpcbData指向的变量中。 In this case, the contents of lpData are undefined. 在这种情况下,lpData的内容是不确定的。

You should NEVER explicitly define the length of the string builders, this value should be got using the method RegQueryInfoKey which will give you the length in bytes of the longest value name, subkey name and value data, which you can then use to initialise the string builders and byte arrays recieving the actual names and data. 您永远不要显式定义字符串生成器的长度,应使用RegQueryInfoKey方法获得此值,该方法将为您提供最长值名称,子项名称和值数据的长度(以字节为单位),您可以将其用于初始化字符串生成器和字节数组,它们接收实际的名称和数据。 This means that you have the smallest possible amount of memory used whilst still being large enough to contain the result. 这意味着您使用的内存量可能最少,同时仍然足够大以容纳结果。 I am pretty sure your problem is in the length you defined for lpValueName. 我很确定您的问题出在为lpValueName定义的长度中。

Also you should use UIntPtr rather than IntPtr and the lpData field should be a byte array if you want the data. 同样,您应该使用UIntPtr而不是IntPtr,并且如果需要数据,则lpData字段应为字节数组。

according to the following sources you should use IntPtr for PBYTE: 根据以下来源,您应该对PBYTE使用IntPtr:

(these are not for your api explicitly but are using PBYTE as well. If you compare c++ values from msdn with the listed links) (这些不是显式用于您的api,而是也在使用PBYTE。如果将msdn中的c ++值与列出的链接进行比较)

you will most likely need to define 您很可能需要定义

    var myIntPtr = Marshal.AllocCoTaskMem(sizeOfMyIntPtr);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM