2013-10-10 66 views
1

我想通过PInvoke的具有以下签名调用从与纯-C接口一个DLL两个函数的PInvoke函数调用:AccessViolationException与双阵列和空指针

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#-code我调用的方法:

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呼叫正常工作和r会产生一个有效的指针。 但调用PjTransformation会引发AccessViolationException - 异常。我认为双数组有问题。 在一篇文章中提到过,一个clr数组已经与本地数组兼容,并且 不需要手动编组。我也尝试过使用双数组的属性[MarshalAs(UnmanagedType.LPArray)],但这没有帮助。或者Exception可以来自第一个函数调用返回的void指针结构。问题是我不知道结构的类型。

dll函数没问题,我用本机c代码试过了,它工作正常。另外参数pointOffset不能导致异常。

+1

您是否尝试过通过在C方法中创建包装来测试您的假设?即创建一个返回'void'而不是struct和p/invoke的C方法。如果这有效,那么结构是问题,你可以调试。如果仍然失败,请创建一个不接受双数组的重载并重试。 –

回答

0

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

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