AccessViolationException в вызове функции PInvoke с двойными массивами и пустыми указателями
Я хочу вызвать две функции из DLL с интерфейсом pure-C через PInvoke со следующими сигнатурами:
void *pj_init_plus(const char *srsName);
int pj_datum_transform(void *src, void *dst, long point_count, int point_offset,
double *x, double *y, double *z );
Pinvoke методы:
[DllImport("proj.dll", CallingConvention = CallingConvention.Cdecl,
EntryPoint = "pj_init_plus", CharSet = CharSet.Ansi)]
public static extern IntPtr PjInit(string srsName);
[DllImport("proj.dll", EntryPoint = "pj_transform", CallingConvention =
CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
public static extern int PjTransformation(IntPtr src, IntPtr dst,long pointCount,
int pointOffset, double[] x, double[] y,double[] z);
В моем C#-коде я вызываю методы:
IntPtr pjSrc = PjInit("+proj=longlat +datum=WGS84 +no_defs");
IntPtr pjDst = PjInit("+proj=utm +zone=32 +ellps=GRS80 +units=m +no_defs");
double[] x = { 4489580.7, 4489580.7 };
double[] y = { 5320767.7, 5320767.7 };
double[] z = { 0.0, 0.0};
PjTransformation(pjSrc, pjDst, x.Length, 1, x, y, z);
PjInit-вызов работает нормально и возвращает действительный указатель. Но вызов PjTransformation создает исключение AccessViolationException-Exception. Я думаю, что есть проблема с двойными массивами. В одном посте было упомянуто, что массив clr уже совместим с собственным массивом и его не нужно маршалировать вручную. Я также попробовал это с атрибутом [MarshalAs(UnmanagedType.LPArray)] для двойных массивов, но это не помогло. Или Исключение может исходить из структуры, которая возвращается как указатель void из первого вызова функции. Проблема в том, что я не знаю тип структуры.
Функции DLL в порядке, я попробовал это с родным C-кодом, и это сработало. Также параметр pointOffset не мог вызвать исключение.
1 ответ
Ваша декларация P-invoke выглядит хорошо и правильно. Единственная проблема, о которой я могу думать, это то, что исключение AV выдается из самой нативной функции, а не когда происходит маршалинг.
Я советую вам попытаться отладить код с помощью встроенного отладчика, вы можете определить точную строку кода, в которой выдается исключение, и определить, возникла ли проблема во время сортировки или фактического выполнения функции.