views:

25

answers:

1

I'm creating a managed C++/CLI DLL that wraps and makes available a single function that resides in a c++ static library.

I got most of it working, except one persistent nagging point.

Here's how the function looks like in my unmanaged lib's .h file.

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

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

and here's what I have so far on the C++/CLI wrapper:

H file:

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 file:

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;
}

Any help is appreciated.

+1  A: 

One way you can get the data from your unmanaged struct to the managed struct is to declare a constructor for the managed struct that accepts a reference to the unmanaged struct like so:

public ref struct MyManagedStruct
{
    float a;
    float b;

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

Note the internal: visibility as the constructor accepts an unmanaged struct, so you don't want it visible from outside the C++/CLI DLL.

With this constructor declared you can then write:

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;
}
mcdave
Thanks for the response. After thinking for a while on what was happening with memory, I ended up using gcnew as well but made the assignment inside the for{}.
Padu Merloti