PInvokeStackImbalance - C # с offreg.dll (windows ddk7) - PullRequest
1 голос
/ 24 марта 2010

Я пытаюсь создать автономный реестр в памяти, используя offreg.dll, предоставленный в пакете windows ddk 7.

Более подробную информацию о файле offreg.dll можно найти здесь: MSDN

В настоящее время при попытке создать улей с помощью ORCreateHive я получаю следующую ошибку:

«Помощник по управляемой отладке« PInvokeStackImbalance »обнаружил проблему. Вероятно, это связано с тем, что управляемая подпись PInvoke не соответствует неуправляемой целевой подписи. Убедитесь, что соглашение о вызовах и параметры подписи PInvoke соответствуют целевой неуправляемой подписи."

Вот файл offreg.h, содержащий ORCreateHive:

    typedef PVOID   ORHKEY;
typedef ORHKEY  *PORHKEY;

VOID 
ORAPI
ORGetVersion(
    __out  PDWORD pdwMajorVersion,
    __out  PDWORD pdwMinorVersion
    );

DWORD
ORAPI
OROpenHive (
    __in  PCWSTR    lpHivePath,
    __out PORHKEY   phkResult
    );

DWORD
ORAPI
ORCreateHive (
    __out PORHKEY   phkResult
    );

DWORD
ORAPI
ORCloseHive (
    __in ORHKEY     Handle
    );

Ниже приведен мой код C #, пытающийся вызвать DLL и создатьуказатель для использования в будущем.

using System.Runtime.InteropServices;

namespace WindowsFormsApplication6
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();

        }

        [DllImport("offreg.dll", CharSet = CharSet.Auto, EntryPoint = "ORCreateHive", SetLastError=true, CallingConvention = CallingConvention.StdCall)]
        public static extern IntPtr ORCreateHive2();

        private void button1_Click(object sender, EventArgs e)
        {
            try
            {
                IntPtr myHandle = ORCreateHive2();
            }
            catch (Exception r)
            {
                MessageBox.Show(r.ToString());
            }
        }
    }
}

В прошлом я мог создавать указатели без проблем, используя user32.dll, icmp.dll и т. д. Однако мне не повезло сoffreg.dll.

Спасибо.

Ответы [ 2 ]

2 голосов
/ 24 марта 2010

Вам необходимо добавить параметр в управляемую подпись, чтобы он соответствовал исходной.

[DllImport("offreg.dll", CharSet = CharSet.Auto, EntryPoint = "ORCreateHive", SetLastError=true, CallingConvention = CallingConvention.StdCall)]
public static extern uint ORCreateHive2(out IntPtr notUsed);

Также, учитывая, что ключ возвращается как выходной параметр, ваш код должен выглядеть следующим образом

IntPtr myHandle;
uint ret = ORCreateHive2(out myHandle);
if ( ret == 0 ) { 
  return myHandle;
} else {
  // Error ...
}
0 голосов
/ 24 марта 2010

Измените его на

extern int ORCreateHive (out IntPtr phkResult);
...