маршалинг типов для работы с типами C ++ - PullRequest
0 голосов
/ 07 января 2011

Я хочу вызвать функцию c ++ (в win32 .dll) на C #.функция c ++ выглядит следующим образом:

bool pack(BYTE * messageFields[]);

функция хочет заполнить некоторые данные (например, строку или байт []) по некоторым индексам входного аргумента.так плз, скажите мне, как маршалинг должен быть в C # .NET?Я перепробовал много типов, но получил ошибки или никаких последствий для моего параметра!

код C # должен открывать native .DLL:

[DllImport("c:\\theDllName.dll")]
        public static extern bool pack( // what is here? )

1 Ответ

1 голос
/ 07 января 2011

System.Byte [] - это то, что вы, вероятно, ищете.

Извините, не заметил, что у вас был BYTE * ... [].

Какой-то код

extern "C" UNMANAGEDCPP_API int fnUnmanagedCpp(BYTE* test[], int nRows, int nCols)
{
    //do stuff
    std::cout << "called!" << std::endl;

    for ( int i = 0; i < nRows; ++i )
    {
        for ( int j = 0; j < nCols; ++j )
        {
            std::cout << int ( test[i][j] ) << std::endl;
        }
    }

    test[0][0] = 23;

    return 0;
}

И в C #:

   [DllImport("UnmanagedCpp.dll", CallingConvention=CallingConvention.Cdecl)]
   public static extern int fnUnmanagedCpp(IntPtr[] buffer, int nRows, int nCols );

   public static IntPtr[] Marshall2DArray(byte[][] inArray)
   {
       IntPtr[] rows = new IntPtr[inArray.Length];

       for ( int i = 0; i < inArray.Length; ++i )
       {
           rows[i] = Marshal.AllocHGlobal(inArray[i].Length * Marshal.SizeOf(typeof(byte)));
           Marshal.Copy( inArray[i], 0, rows[i], inArray[i].Length );
       }

       return rows;
   }

   public static void Copy2DArray( IntPtr[] inArray, byte[][] outArray )
   {
       Debug.Assert(inArray.Length == outArray.Length);

       int nRows = Math.Min( inArray.Length, outArray.Length );

       for (int i = 0; i < nRows; ++i)
       {
           Marshal.Copy(inArray[i], outArray[i], 0, outArray[i].Length);
       }
   }

   public static void Free2DArray(IntPtr[] inArray)
   {
       for (int i = 0; i < inArray.Length; ++i)
       {
           Marshal.FreeHGlobal(inArray[i]);
       }
   }

    static void Main(string[] args)
    {
        byte[][] bTest = new byte[2][] { new byte[2] { 1, 2 }, new byte[2] { 3, 4 } };

        IntPtr[] inArray = Marshall2DArray(bTest);

        fnUnmanagedCpp(inArray, 2, 2);

        Copy2DArray(inArray, bTest);
        Free2DArray(inArray);

        System.Console.WriteLine(bTest[0][0]);
    }

Надеюсь, это поможет, может быть, есть другой лучший / более простой способ сделать это.Обратите внимание, что код предназначен только для «иллюстрации» и может содержать ошибки.

По существу, каждый передает массив IntPtrs и маршалы вручную ...

...