AccessViolationException in PInvoke 函数调用,带有双数组和 void 指针

本文关键字:数组 void 指针 in PInvoke 函数调用 AccessViolationException | 更新日期: 2023-09-27 18:34:52

我想通过具有以下签名的 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(],但这没有帮助。或者异常可能来自结构,该结构作为第一个函数调用的 void 指针返回。问题是我不知道结构的类型。

dll 函数还可以,我尝试使用本机 c 代码并且它有效。此外,参数 pointOffset 不会导致异常。

AccessViolationException in PInvoke 函数调用,带有双数组和 void 指针

你的 P 调用声明看起来不错且有效。我能想到的唯一问题是 AV 异常是从本机函数本身而不是在封送处理发生时引发的。

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