Предположим, что существует метод C++ int NativeMethod(double, double *)
в Native.dll. Моя первая попытка вызова этого метода из управляемого кода была (предположение, что я не должен указывать точку входа),
[DllImport("Native.dll")]
private static extern int NativeMethod(double inD, IntPtr outD);
Затем для использования DLL я сделал
IntPtr x = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(IntPtr)));
NativeMethod(2.0, x);
//do stuff with x
Marshal.FreeHGlobal(x); //crash
Я хотел бы понять, почему это отказывает здесь. Мое первое предположение - то, что это - проблема "кучи" вследствие того, что DLL и мое приложение могли использовать другой CRT. Но если это имело место, почему не будет вызов к катастрофическому отказу NativeMethod вместо этого? Метод возвратил x, из которого я мог успешно извлечь двойное.
Я могу заставить импорт работать путем передачи двойного ссылкой
[DllImport("Native.dll")]
private static extern int NativeMethod(double inD, IntPtr outD);
Почему FreeHGlobal отказывает в первой попытке, и что рекомендуемый путь состоит в том, чтобы передать указатели на собственные методы? Ключевое слово может хорошо работать эта ситуация, но что, если я должен был Упорядочить строку? Я не думаю, что могу обойти AllocH и FreeH...
Проблема в том, что метод принимает double *
, который является указателем на double. Вы передаете указатель, указывающий на IntPtr
. Это важно только потому, что существует разница в размере между double
(8 байтов) и IntPtr
, размер которых может изменяться (4 или 8 байтов). Вам нужно выделить указатель на double
IntPtr x = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(double));
Возможно, я неправильно понимаю вашу цель, но похоже, что вы усложняете ее, чем необходимо. Просто передайте его по ссылке, и пусть об этом позаботится сортировка внизу.
[DllImport("Native.dll")]
private static extern int NativeMethod(double inD, ref double outD);
double x;
x = 1;
NativeMethod( 2.0, ref x );
Я не эксперт, но не должно ли это быть:
IntPtr x = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(double)));