2013-10-10 82 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異常是從本地函數本身拋出的,而不是在編組發生時拋出。

我建議您嘗試使用本地調試器調試代碼,您可以發現引發異常的確切代碼行,並在編組或實際功能執行期間發生問題時進行診斷。