Вызов массива байтов - PullRequest
       26

Вызов массива байтов

0 голосов
/ 22 апреля 2009

У меня есть следующий код C:

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?

Ответы [ 3 ]

1 голос
/ 22 апреля 2009

Почему так много людей хотят избежать 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<> и тому подобным. Но вы получите общее представление.

1 голос
/ 23 апреля 2009

Поскольку в 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());
}
1 голос
/ 22 апреля 2009

Я не могу гарантировать, что это лучший способ, но я бы попробовал первый.

    [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);
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...