2016-12-09 57 views
0

我目前正試圖讓一個非託管(c)DLL在我的c#應用程序中工作。我遇到的問題是將結構傳遞給非託管函數。C#Interop - 如何傳遞一個C結構,可以由C作爲一個數組結構訪問

我已經導入功能,像這樣(使用的PInvoke互操作助理)...

[System.Runtime.InteropServices.DllImportAttribute("myDll.dll", EntryPoint = "ListDevices")] 
public static extern int ListDevices(ref Device_t devices, ref int DevicesCount); 

我試圖通過該結構...

[System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential, CharSet = System.Runtime.InteropServices.CharSet.Ansi)] 
    public struct Device_t 
    { 
     /// int 
     public int Address; 

     /// int 
     public int GearAddress; 

     /// int 
     public int Id; 

     /// char[8] 
     [System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.ByValTStr, SizeConst = 8)] 
     public string Rev; 
    } 

在DLL的代碼的功能(無關代碼刪除)...

static int listDevices(Device_t *devices, int *deviceCount) 
{ 
    char *pch; 
    int i; 
    char *token; 
    int paramCount; 
    Device_t device; 

    // code removed // 

    while (token != NULL) 
     { 
      pch = strstr(token, "ENTRY"); 
      if (pch != NULL) 
      { 
       paramCount = sscanf(&token[0], "%*d ..... %d",   
       &device.Address, &device.GearAddress, &device.Rev, 
       &device.Id); 
       if (paramCount == 4) 
       { 
        devices[i].Address = device.Address; 
        devices[i].GearAddress = device.GearAddress; 
        devices[i].Id = device.Id; 
        strcpy(devices[i].Rev, device.Rev); 
        i++; 
       } 
      } 
      token = strtok(NULL, "#"); 
     } 

    // code removed // 
} 

主要問題是,c代碼訪問'Device_t設備'變量ble作爲數組,但c#函數只接受單個Device_t。 我相信在結構中的字符串的存在使其不易blittable,使事情進一步複雜化:(

理想情況下,我希望能夠在c#中聲明一個Device_t數組,可以通過c訪問,米意識到陣列在C#中的結構不同和C相比。

+0

一個非常簡單的出路是到您的解決方案的C++/CLI程序集。 –

回答

0

我發現這個問題,這是我被封送處理DLL函數的方式。

兩個In和Out屬性需要被指定。

[System.Runtime.InteropServices.DllImportAttribute("myDll.dll", EntryPoint = "ListDevices")] 
public static extern int ListDevices([In, Out] Device_t[] devices, ref int DevicesCount);