Как я могу передать двоичный двоичный объект из C ++ в C #? - PullRequest
1 голос
/ 19 мая 2011

Я в первую очередь разработчик C # (не так много C ++ с тех пор, как учился в колледже), но я работаю над интеграцией большого набора кода C ++ в приложение. У меня есть сборка C ++ / CLI, которая буферизует эти два мира, и у меня нормально работает связь от C # до C ++. Вопрос, который у меня возникает, заключается в том, что в классе C ++ есть вызов метода, который генерирует двоичный двоичный объект (например, массив byte s в мире C #), который мне нужно получить в C # и обработать (передать как сплошной пакет).

То, что я ищу, - это совет о том, как обрабатывать метод буфера / оболочки (C ++ / CLI) между двумя мирами. Я предполагал, что передал бы char* и длину, но C # видит это как byte* (я предполагаю, что это некоторая "магия" C ++ / CLI).

Я также пытался передать array<Byte ^>^, но мне не повезло, что char* из остальной части C ++ lib в массив byte ... не получилось.

Ответы [ 3 ]

3 голосов
/ 19 мая 2011

Вы можете использовать UnmanagedMemoryStream, например, так:

byte[] message = UnicodeEncoding.Unicode.GetBytes("Here is some data.");
IntPtr memIntPtr = Marshal.AllocHGlobal(message.Length);
byte* memBytePtr = (byte*) memIntPtr.ToPointer();

UnmanagedMemoryStream writeStream = new UnmanagedMemoryStream(memBytePtr, message.Length, message.Length, FileAccess.Write);

writeStream.Write(message, 0, message.Length);
writeStream.Close();

Обратный маршрут, примерно:

UnmanagedMemoryStream readStream = new UnmanagedMemoryStream(memBytePtr, message.Length, message.Length, FileAccess.Read);

byte[] outMessage = new byte[message.Length];
readStream.Read(outMessage, 0, message.Length);
readStream.Close();

// Convert back into string for this example
string converted = UnicodeEncoding.Unicode.GetString(outMessage);

Marshal.FreeHGlobal(memIntPtr);

Я уверен, что у MSDN будет больше ресурсов

3 голосов
/ 19 мая 2011

Пусть код C ++ / CLI передает System::IO::UnmanagedMemoryStream коду C #, который затем может использовать System.IO.BinaryReader в указанном потоке для извлечения данных по мере необходимости.

Кроме того, C ++ / CLI char является синонимом C # sbyte, C ++ / CLI unsigned char является синонимом C # byte, C ++ / CLI wchar_t является синонимом C # * charи C ++ / CLI array<unsigned char>^ является синонимом C # byte[].Обратите внимание, что это array<unsigned char>^ или array<System::Byte>^, а не array<unsigned char^>^ или array<System::Byte^>^, поскольку System.Byte является типом значения, а не типом ссылки.

2 голосов
/ 19 мая 2011

Я выстрелил в него и придумал это. Ничего сумасшедшего, просто выделите управляемый массив, скопируйте данные и верните их.

Заголовок:

#pragma once
using namespace System;
using namespace System::Runtime::InteropServices;
namespace CLRLib
{
    public ref class TwiddlerFunctions
    {
    public:
        static array< Byte >^ GetArray();
    };
}

реализация:

#include "CLRLib.h"
array< Byte >^ CLRLib::TwiddlerFunctions::GetArray()
{
    unsigned char data[] = { 1, 2, 34, 5 };
    // convert the unmanaged array to a managed array
    array< Byte >^ arr = gcnew array< Byte >(sizeof data);
    Marshal::Copy((IntPtr)data, arr, 0, arr->Length);
    return arr;
}

C # сторона:

using System;
using CLRLib;
class Program
{
    static void Main(string[] args)
    {
        byte[] arr = TwiddlerFunctions.GetArray();
        Console.WriteLine(String.Join(" ", arr)); // 1 2 34 5
    }
}
...