Корректное использование DllImport

Предположим, что существует метод 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...

7
задан Darin Dimitrov 13 July 2010 в 14:51
поделиться

3 ответа

Проблема в том, что метод принимает double * , который является указателем на double. Вы передаете указатель, указывающий на IntPtr . Это важно только потому, что существует разница в размере между double (8 байтов) и IntPtr , размер которых может изменяться (4 или 8 байтов). Вам нужно выделить указатель на double

IntPtr x = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(double));
5
ответ дан 6 December 2019 в 15:18
поделиться

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

[DllImport("Native.dll")]
private static extern int NativeMethod(double inD, ref double outD);

double x;

x = 1;
NativeMethod( 2.0, ref x );
7
ответ дан 6 December 2019 в 15:18
поделиться

Я не эксперт, но не должно ли это быть:

IntPtr x = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(double)));
2
ответ дан 6 December 2019 в 15:18
поделиться
Другие вопросы по тегам:

Похожие вопросы: