Mixed mode assembly wrapper

G

Guest

Hi,

I am making a wrapper class so I can call unmanaged classes from C#, I
have these structs that I want to pass and get back from the unmanaged
classes, do I...


1) Create a copy of these structs for the managed world like
public __value struct SomeStruct
{
System::UInt32 SomeVal;
System::UInt32 SomeVal2;
System::UInt32 SomeVal3;
}

and use these from C# and then pass this to the method wrapper, that is
calling the unmanaged method like...
someReferenceToObject->someMethod(..., SomeStruct);

or 2)
do I make it like so..

public __gc class SomeThing
{
private: SOMEUNMANAGEDTHING* someUnmanagedThing;

public: SomeThing()
{
someUnamangedThing = new SOMEUNMANAGEDTHING();
}

public: ~SomeThing()
{
delete someUnmanagedThing;
}

// private so only the genereated prop is visible
private: __property System::UInt32 get_SomeVal()
{
return someUnmanagedThing->SomeVal;
}

// private so only the genereated prop is visible
private: __property void get_SomeVal(System::UInt32 value)
{
someUnmanagedThing->SomeVal = value;
}
}

and passt his to the unmanaged method like previously?

Whats the best way to make unmanaged structs visible to the managed world?

Thanks
 
G

Guest

Im still learning this mix mode stuff..


If I make a duplicate of the struct, can I somehow pass this into the
method without doing.

System::UInt32 someMethod(SomeStruct s)
{
SOMEUNMANAGEDSTRUCT* something = new SOMEUNMANAGEDSTRUCT;

something->someVal = s.SomeVal;
something->someVal2 = s.SomeVal2;
something->someVal3 = s.SomeVal3;

return someObj->someMethod(something);
}
 
N

Niel Sutton [MSFT]

Hello,

If I understand the question correctly, a Managed C++ (MC++) wrapper class
is being written to expose unmanaged structs in an existing C++ class to
C#. Please let me know if this is not correct.

Either of the two methods that have been proposed will work, but each has
its own caveats.

Whenever a managed type is created using either __gc or __value keywords,
the CLR makes determinations about the layout and management of memory as
necessary. Because of this, a couple of things are needed to ensure that
interop will work as expected.

For number 1, we must use the following to specify that they type must have
its data members laid out in the given order:

using namespace System::Runtime::InteropServices;

[StructLayoutAttribute(LayoutKind::Sequential)]
public __value struct SomeStruct
{
System::UInt32 SomeVal;
System::UInt32 SomeVal2;
System::UInt32 SomeVal3;
}


If you want to go with number 2, then when the SomeThing object is
allocated with new it is placed on the GC heap and then the GC can move the
object around whenever and wherever it wants. To prevent this, use the
__pin keyword to pin the pointer before making calls to unmanaged code.


Thanks!
Niel Sutton
Microsoft C++/C# Developer Support
This posting is provided "AS IS" with no warranties, and confers no rights.
 
J

John Biddiscombe

If you want to go with number 2, then when the SomeThing object is
allocated with new it is placed on the GC heap and then the GC can move the
object around whenever and wherever it wants. To prevent this, use the
__pin keyword to pin the pointer before making calls to unmanaged code.

If the unmanaged object is being called from managed code - why does the
managed object being moved around matter? (If the unmanaged code was calling
into the managed code, I'd understand),

thanks

JB
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top