1

我想通过具有以下签名的 PInvoke 从具有纯 C 接口的 DLL 调用两个函数:

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-array 已经与本机数组兼容,无需手动编组。我还尝试使用双数组的属性 [MarshalAs(UnmanagedType.LPArray)] ,但这没有帮助。或者异常可能来自第一个函数调用作为空指针返回的结构。问题是我不知道结构的类型。

dll函数没问题,我用本机c代码试了一下,效果很好。参数 pointOffset 也不会导致异常。

4

1 回答 1

0

您的 P-invoke 声明看起来不错且有效。我能想到的唯一问题是 AV 异常是从本机函数本身引发的,而不是在编组发生时引发的。

我建议您尝试使用本机调试器调试代码,然后您可以找出引发异常的确切代码行并诊断问题是否在编组或实际函数执行期间发生。

于 2013-10-10T19:04:12.557 回答