2009-04-22 25 views
0

數組我有下面的C代碼:的PInvoke一個字節數組

const BYTE* Items[3]; 
Items[0] = item1; 
Items[1] = item2; 
Items[2] = item3; 
int result = Generalize(3, Items); 

與具有

int __stdcall Generalize(INT count, const BYTE * const * items); 

是什麼力量讓與的PInvoke該呼叫的最佳方式簽名廣義含?

+0

你試過了哪些方法? – 2009-04-22 18:51:41

回答

1

我不能保證這是最好的方式,但這是我嘗試的第一種方式。

[DllImport("<unknown>", 
      EntryPoint="Generalize", 
      CallingConvention=CallingConvention.StdCall)] 
    public static extern int Generalize(int count, IntPtr[] items); 

    public static void CallGeneralize() 
    { 
     var itemCount = 3; 
     var items = new IntPtr[itemCount]; 

     items[0] = item1; // where itemX is allocated by Marshal.AllocHGlobal(*) 
     items[1] = item2; 
     items[2] = item3; 

     var result = Generalize(itemCount, items); 
    } 
+0

這工作。將問題留待另一小時左右,看看是否有人發現更優雅的東西。 – JasonRShaver 2009-04-22 19:12:42

+0

謝謝Micha =) – JasonRShaver 2009-04-29 16:34:05

1

爲什麼看起來這麼多人想避免C++/CLI?如果您不得不問如何使用P/Invoke,那可能是提示使用C++/CLI來代替。

沿JasonRShaver.h

namespace StackOverflow 
{ 
    public ref class JasonRShaver abstract sealed // "abstract sealed" -> "static" 
    { 
     public: 
    static int Generalize(array<array<BYTE>^>^ items) { 
     int count = items->Length; 
     std::vector<const BYTE*> arrays(count); 

     for each (array<BYTE>^ a in items) 
     { 
      BYTE* bytes = new BYTE[a->Length]; 
      for (int i=0; i<a->Length; i++) 
       bytes[i] = a[i]; 
      arrays.push_back(bytes); 
     } 

     int retval = ::Generalize(count, &(arrays[0])); 

     typedef std::vector<const BYTE*>::const_iterator it_t; 
     for (it_t it = arrays.begin(); it != arrays.end(); ++it) 
     { 
      const BYTE* bytes = *it; 
      delete[] bytes; 
     } 

     return retval; 
    } 

    }; 
} 

這下面的東西線是不是生產質量的代碼(例如,異常處理),你可能能夠做到,甚至做得更好與pin_ptr<>等。但你得到了一般想法。

+0

是的,那樣會更好,但是那裏有一個相當數量的「其他」代碼,這是唯一存在問題的方法。 – JasonRShaver 2009-04-22 19:14:13

1

由於C++沒有鋸齒陣列,只有多維數組並且使用row * column訪問元素,因此可以在調用之前嘗試展平多維數組。

[DllImport("dllName.dll")] 
private static extern int Generalize(int count, ref byte[] items); 

public static int Generalize(int count, byte[,] items) 
{ 
    return Generalize(count, ref items.Cast<byte>().ToArray()); 
}