Как передать управляемые массивы по ref в неуправляемую библиотеку? - PullRequest
1 голос
/ 01 июля 2010

Я создаю управляемую C ++ / CLI DLL, которая оборачивает и делает доступной одну функцию, находящуюся в статической библиотеке c ++.

Большая часть ее работала, за исключением одной постоянной проблемы.

Вот как эта функция выглядит в .h файле моей неуправляемой библиотеки.

typedef struct 
{
    float a;
    float b;
}MyStruct;

bool GetData(float p1, float* p2, MyStruct buffer[]);

и вот что у меня есть в оболочке C ++ / CLI:

H файл:

using namespace System::Runtime::InteropServices

public ref struct MyManagedStruct
{
    float a;
    float b;
}

public ref class Wrapper
{
    bool static GetDataManaged(
      float p1, [Out] float %p2, 
      array<MyManagedStruct^> ^ managedBuffer);
}

Файл CPP:

bool Wrapper::GetDataManaged(
    float p1, [Out] float %p2,
    array<MyManagedStruct^> ^ managedBuffer)
{
    float f;

            //managed buffer is assumed allocated by the .net caller
    MyStruct* unmanagedBuffer = new MyStruct[managedBuffer->Length];

    bool retval = GetData(p1, &f, unmanagedBuffer);

            /* this doesn't work... any better suggestions?
    for (int i=0;i<n;i++)
        BallDatabuffer[i] = buffer[i];
            */

    p2 = f;

    return retval;
}

Любая помощь приветствуется.

1 Ответ

2 голосов
/ 01 июля 2010

Один из способов получить данные из неуправляемой структуры в управляемую структуру - это объявить конструктор для управляемой структуры, который принимает ссылку на неуправляемую структуру, например:

public ref struct MyManagedStruct
{
    float a;
    float b;

internal:
    MyManagedStruct(const MyStruct &s)
    {
        a = s.a;
        b = s.b;
    }
};

Обратите внимание на internal: видимость, поскольку конструктор принимает неуправляемую структуру, поэтому вы не хотите, чтобы она была видна извне C ++ / CLI DLL.

С этим объявленным конструктором вы можете написать:

bool Wrapper::GetDataManaged(
    float p1, [Out] float %p2,
    array<MyManagedStruct^> ^ managedBuffer)
{
    float f;

    //managed buffer is assumed allocated by the .net caller
    MyStruct* unmanagedBuffer = new MyStruct[managedBuffer->Length];
    int n = managedBuffer->Length;

    bool retval = GetData(p1, &f, unmanagedBuffer);

    for (int i=0;i<n;i++)
        managedBuffer[i] = gcnew MyManagedStruct(unmanagedBuffer[i]);

    p2 = f;

    return retval;
}
...