DSomesh Ответов: 2

Второе значение не передается функции C++ во время pininvoke.


У меня есть функция c++, которую я вызываю из c# с помощью pinInvoke. Ниже приведен мой метод cpp-

int test(DWORD verb,DWORD verb2 )
{
	return verb2 *100;
}


Моя функция выставляется как -

extern "C" {
	__declspec(dllexport) int test(DWORD verb, DWORD verb2);
}


Ниже приведен мой код c#, в котором я вызываю описанный выше метод:

общедоступный API класса
{
[Атрибута DllImport("mydll.dll", точка входа = "тест", функции setlasterror = true, то CallingConvention = CallingConvention.Ключевое слово cdecl)]
[return: MarshalAs(UnmanagedType. U4)]
публичный статический тест extern uint(
[MarshalAs(UnmanagedType. U8)] ulong глагол,
[MarshalAs(UnmanagedType. U8)] ulong verb2
);

static void Main (string[] args)
{
uint с х = с помощью dpapi.тест(26,10);
Приставка.Напишите ("результат - "+x);
}
}

Здесь второе значение передается как 0, так что получается неправильный результат.Я делаю что-то не так, передавая значение?

Что я уже пробовал:

Я относительно недавно в Пинвоке. Поэтому я попытался отладить, чтобы увидеть, не передается ли значение в код c++ или код c++ не возвращает правильные значения.Я обнаружил, что значение, передаваемое само по себе, было неправильным.

2 Ответов

Рейтинг:
16

CPallini

Цитата:
[MarshalAs(UnmanagedType. U8)] ulong глагол,
[MarshalAs(UnmanagedType. U8)] ulong verb2
Так и должно быть, вместо этого
[MarshalAs(UnmanagedType.U4)] uint verb,
[MarshalAs(UnmanagedType.U4)] uint verb2

или просто:
uint verb,
uint verb2


Pete O'Hanlon

Мой 5.

DSomesh

Сегодня всплыла еще одна похожая история..Поэтому я передавал два значения (long as unamanagedtype.I8 и int как неуправляемый тип.I4) и в моем коде c++ оба значения были DWORD. Согласно вашему объяснению выше, это не должно было сработать. Но в моем случае он работал правильно для 64-битной машины, но в случае 32-битного второго значения всегда было 0. Я знаю, что поступил неправильно, но хотел бы знать, почему он так себя вел.Не хотите ли объяснить это поведение?

CPallini

Вы можете объяснить это сами: просто выведите sizeof (long) на обеих машинах.

Рейтинг:
1

Pete O'Hanlon

Что - то, о чем вам нужно знать-DWORD зависит от версии Windows. Итак, на 32-битной машине DWORD-это 32 бита. На 64-битной машине это 64 бита. Что еще более важно, DWORD - это uint (а не ulong).

Edit: как заметил Карло - я думал о DWORD_PTR, а не о DWORD. Однако точка зрения о том, что DWORD является uint, все еще остается в силе.


CPallini

DWORD имеет 32 бита, как на 32-битных, так и на 64-битных машинах. Я полагаю, это из соображений совместимости.

Pete O'Hanlon

Дох! Я думал о DWORD_PTR. Спасибо.

CPallini

На мой взгляд, это довольно запутанно.
Кстати, спасибо тебе и возьми мою 5-ю.