У меня есть очень простой вызов с С# на С++. Вызов функции принимает три параметра:
extern "C" int CLIENT_API example(const char, char * const, const unsigned int);
Код C# импортирует эту функцию как:
[DllImport("my.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern int example(in sbyte id, byte[] buffer, in uint bufferSize);
Когда я вызываю функцию из С# следующим образом:
uint bufferSize = 400;
byte[] buffer = new byte[bufferSize];
example(0, buffer, bufferSize);
Я регистрирую значения варианта размера C++ как для id, так и для bufferSize (каждый запуск имеет разные значения для этих двух переменных). Что я делаю не так? У меня есть другие функции взаимодействия, которые передают указатели и строки в мою C++ DLL, и у них нет никаких проблем. Похоже, это просто происходит с более примитивными типами byte и uint.





Модификатор in делает аргумент ref доступным только для чтения. Это не то же самое, что атрибут [In], который является сортировочной подсказкой.
Вы передаете 0 и bufferSize, а C# берет их адреса (буквальные 0 в виде временной переменной) и передает их.
Вы получаете разные значения, потому что адрес каждый раз разный.
Удалите модификаторы in, чтобы C# передавал эти значения, а не адреса.
Не используйте
inв объявлениях pinvoke, это чистая хакорама C# для маскировки указателя. Ужасный хак от команды Roslyn, борющийся с производительностью компиляции при переходе с C++ на C#. Значения, которые вы видите, выглядят случайными, потому что реальное переданное значение (указатель) непредсказуемо. Просто удалитеin.