次のシグネチャを持つ PInvoke を介して、純粋な C インターフェイスを使用して DLL から 2 つの関数を呼び出したいと考えています。
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-Exception がスローされます。二重配列に問題があると思います。ある投稿では、clr-array は既にネイティブ配列と互換性があり、手動でマーシャリングする必要がないことが言及されました。二重配列の属性 [MarshalAs(UnmanagedType.LPArray)] も試しましたが、役に立ちませんでした。または、最初の関数呼び出しから void ポインターとして返される構造体から例外が発生する可能性があります。問題は、構造体の型がわからないことです。
dll 関数は問題ありません。ネイティブの C コードで試してみたところ、うまくいきました。また、パラメーター pointOffset によって例外が発生することはありませんでした。