Мне нужно вызвать метод C ++ через dllimport. Все работает нормально, если в методе c ++ нет двух следующих параметров:
const void * key,
void * out
Я думаю, что мне нужно собрать их. Но как это работает?
Ключ должен быть указателем на байтовый массив, а параметр out также является байтовым массивом длиной 16.
После попытки того, что предлагает Jcl, у меня есть следующее:
Используя первый метод (используйте byte [] outprm), программа завершает работу без ошибок (при достижении точки вызова).
Но, используя второй способ (из комментария Jcl), у меня есть следующее:
[DllImport(@"MyDLL.dll", SetLastError = true)]
public static extern void MyMethod(IntPtr key, out IntPtr outprm);
private void button1_Click(object sender, EventArgs e)
{
byte[] hash = new byte[16];
byte[] myArray = new byte[] { 1, 2, 3 };
IntPtr outprm = Marshal.AllocHGlobal(hash.Length);
IntPtr key = Marshal.AllocHGlobal(myArray.Length);
Marshal.Copy(myArray, 0, key, myArray.Length);
MyMethod(key, out outprm);
Marshal.Copy(outprm, hash, 0, 16);
Marshal.FreeHGlobal(key);
}
Теперь нет ошибки при вызове MyMethod. Я просто получаю следующую ошибку при попытке скопировать данные обратно: AccessViolationException
Он сказал, что я хочу записать в защищенную память. Программное обеспечение dll и c # — x64 (и должно быть x64). Может быть, это причина?
использование IntPtr
как для ключа, так и снаружи, что-то вроде:
[DllImport ("whatever.dll")]
public static extern void MyMethod(IntPtr key, IntPtr outprm);
Делать key
быть IntPtr, принимая myArray
будучи байтовым массивом:
IntPtr key = Marshal.AllocHGlobal(myArray.Length);
Marshal.Copy(myArray, 0, key, myArray.Length);
// ... call your function ...
Marshal.FreeHGlobal(key );
Чтобы получить 16-байтовый массив из outprm
:
IntPtr outprm;
MyMethod(key, outprm);
byte [] myArray = new byte[16];
Marshal.Copy(outprm, myArray, 0, 16);
Других решений пока нет …