PInvoke一个字节数组的数组

时间:2009-04-22 18:07:22

标签: c# c++ pinvoke

我有以下C代码:

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

使用Generalize签名

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

使用PInvoke拨打电话的最佳方式是什么?

3 个答案:

答案 0 :(得分: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);
    }

答案 1 :(得分: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<>等更好的工作。但是你得到了一般的想法。

答案 2 :(得分: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());
}