2015-01-16 111 views
1

我想(在過去的10小時.... GRR),使這件事情的工作,但到目前爲止,無論我嘗試 - 它拒絕:)封送數組c結構的爲C#

基本上我在做什麼一個人的青睞 - 我的實力不是Windows/.NET的編碼,我試圖從我已經擁有的某些代碼中修補代碼。

什麼問題?

我想調用一個C DLL庫方法返回一個2d數組結構的C#。

但似乎我做錯了關於如何從c#中讀取數據。

我開發了一個簡單的C控制檯應用程序,我從那裏調用了DLL - 一切正常 - 完全沒有問題。只有c#失敗!

下面是C語言實現的方法:

int get_available_devices(idevice_info_t **devices, uint32_t *count) { 
char **dev_list = NULL; 
char *dev_name = NULL; 
int i, total_devices; 

if (idevice_get_device_list(&dev_list, &total_devices) < 0) { 
    fprintf(stderr, "ERROR: Unable to retrieve device list!\n"); 
    return -1; 
} 

idevice_info_t *tmpArr = (idevice_info_t*)calloc(total_devices, sizeof(idevice_info)); 

int ii = 0; 
int res_name = 0; 

idevice_info_t dtmp = NULL; 

for (i = 0; i <= total_devices - 1; i++) { 
    res_name = idevice_get_device_name(dev_list[i], &dev_name); 
    dev_name = (res_name == 0 ? dev_name : ""); 

    printf("%s: %s\n", dev_name, dev_list[i]); 

    dtmp = (idevice_info_t)malloc(sizeof(struct idevice_info)); 
    strncpy_s(dtmp->udid, sizeof dtmp->udid - 1, dev_list[i], sizeof dtmp->udid - 1); 
    strncpy_s(dtmp->name, sizeof dtmp->name - 1, dev_name, sizeof dtmp->name - 1); 
    tmpArr[i] = dtmp; 
} 
idevice_device_list_free(dev_list); 

*devices = tmpArr; 
*count = total_devices; 

return 0;} 

下面是我在做什麼在C#中端:

[DllImport(LIBNAME, CallingConvention = CallingConvention.Cdecl)] 
    static public extern short get_available_devices(out IntPtr devices, out uint count); 

public static Dictionary<string, string> getAvailableDevices() 
    { 
     IntPtr p = IntPtr.Zero; 
     Dictionary<string, string> ret = null; 

     uint totalDevices = 0; 

     int res = External.get_available_devices(out p, out totalDevices); 

     if (res != 0 || totalDevices < 1) 
     { 
      return null; 
     } 

     ret = new Dictionary<string, string>(); 

     External.idevice_info ppStruct; 
     int sSize = Marshal.SizeOf(typeof(External.idevice_info)); 

     for (int i = 0; i <= totalDevices - 1; i++) 
     { 
      p = (IntPtr)Marshal.PtrToStructure(p, typeof(IntPtr)); 
      ppStruct = (External.idevice_info)Marshal.PtrToStructure(p, typeof(External.idevice_info)); 

      ret.Add(ppStruct.udid, ppStruct.name); 

      p = new IntPtr(p.ToInt64() + sSize); 
     } 

     return ret; 
    } 

什麼實際問題?

只要我到達的第二次迭代週期爲()我得到一個訪問衝突:

An unhandled exception of type 'System.AccessViolationException' occurred in mscorlib.dll 

Unhandled exception: Access Violation

我想我不能正確計算指針,但......我真的嘗試了很多不同的場景,沒有任何效果。

幫助! :)

回答

1

您正在提領pp = (IntPtr)Marshal.PtrToStructure(p, typeof(IntPtr));,然後在最後嘗試增加時,所有的地獄崩潰。

使用一個新的本地,使原始指針不連續解除引用。

如:

for (int i = 0; i <= totalDevices - 1; i++) 
    { 
     IntPtr pp = (IntPtr)Marshal.PtrToStructure(p, typeof(IntPtr)); 
     ppStruct = (External.idevice_info)Marshal.PtrToStructure(pp, 
         typeof(External.idevice_info)); 

     ret.Add(ppStruct.udid, ppStruct.name); 

     p += sSize; // easier, does the same :) 
    } 
+0

我seeee :)但它仍然變壞:(第1期是(P + = sSize)不工作 - 我是在3.5 SDK - 我想這就是原因所在 - 所以我已經用p = new IntPtr(p.ToInt64()+ sSize)替換它; 現在的異常是不同的:NullReferenceException - 再次在'ppstruct = ...'行,在調用' p'已成爲零。 –

+1

Aaand我剛剛解決了它:)))我應該做的:p = new IntPtr(p.ToInt64()+ IntPtr.Size);而不是:p = new IntPtr(p.ToInt64()+ sSize);現在全部完美!謝謝BIG !!!!!! –

+0

@MartinKovachev:很高興我能幫忙:D'p + = IntPtr.Size;'也可以工作 – leppie