1

次のシグネチャを持つ 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 によって例外が発生することはありませんでした。

4

1 に答える 1