Я хочу вызвать две функции из DLL с чистым 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 );
Пинвок методы:
[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. Я думаю, что есть проблема с двойными массивами. В одном сообщении упоминалось, что clr-массив уже совместим с собственным массивом и не требует сортировки вручную. Я также попробовал это с атрибутом [MarshalAs(UnmanagedType.LPArray)] для двойных массивов, но это не помогло. Или может возникнуть исключение из структуры, которая возвращается в виде указателей void из первого вызова функции. Проблема в том, что я не знаю тип структуры.
Функции dll в порядке, я попробовал это с собственным кодом C, и это сработало. Также параметр pointOffset не мог вызвать исключение.
void
вместо структуры, и p/вызовите это. Если это работает, то проблема заключается в структуре, и вы можете ее отладить. Если это все еще не удается, создайте перегрузку, которая не принимает двойные массивы, и повторите попытку. - person Patrick Quirk   schedule 10.10.2013