Reputation: 20684
In C++, I create this class:
public ref class UConfig
{
public:
UConfig(short nr);
~UConfig();
bool checkNr();
private:
short _nr;
}
and a public class in C++ that will be called in C#:
public ref class UConfigHandler
{
public:
UConfigHandler(UConfig^ uConfig);
}
Then in C#, I can do it like this:
UConfig uConfig = new UConfig(1);
UConfigHandler uConfigHandler = UConfigHandler(uConfig);
in C++, I debug it and I inside the constructor:
UConfigHandler::UConfigHandler(UConfig^ uConfig)
{
// while debugging I see that uConfig is: System::Object^
// how to do the conversion from the uConfig to UConfig inside C++
// I would like to do something like this but I got an exception
UConfig myConfig = uConfig; // the program is stopped here but I dont know what is the error
}
So, basically I want to convert the System::Object^ uConfig to the native UConfig. How can I do that?
Something I have done similar with String^ to string:
input is String^
IntPtr stringPointer = (IntPtr)Marshal::StringToHGlobalAnsi(input);
string retrievedString = string((char*)stringPointer.ToPointer());
Upvotes: 3
Views: 4179
Reputation: 4381
What are you trying to do? The UConfig^
you receive in the constructor of ConfigHandler
is a perfectly valid handle to a UConfig
.NET instance. There is no need to marshal, cast or do anything special about it.
So, basically I want to convert the System::Object^ uConfig to the native UConfig. Could you please tell me how can I do it?
There is no native UConfig
in the code snippet you've posted. You create an instance in C# and pass it to the ConfigHandler
which stores a reference to it:
public ref class ConfigHandler {
Config^ mConfig;
public:
ConfigHandler(Config^ pConfig) : mConfig(pConfig) {}
};
You could even define the ConfigHandler
in a completely different assembly using C#, there would be no difference. Well almost none, your ConfigHandler
defined in C++/CLI will implement IDisposable, but since it does not store any unmanaged resources it does not matter. Hm, are you aware of the fact that you are not writing C++ but C++/CLI which is a huge difference?
Upvotes: 2
Reputation: 40395
You're trying to assign a handle of a UConfig
instance to a UConfig
object. You've declared UConfig^ uConfig
as a reference, therefore you can only assign it to a reference.
It would be the equivalent in C++ if you did this:
MyClass* mcp = new MyClass();
MyClass mcv = mcp;
In other words, your UConfigHandler
constructor should look like this:
UConfigHandler::UConfigHandler(UConfig^ uConfig)
{
UConfig^ myConfig = uConfig;
}
You might be able to do it... you can marshal a struct
so you should be able to marshal a class
too. I haven't done that, but the documentation of Marshal.StructureToPtr gives a similar example:
// Initialize unmanged memory to hold the struct.
IntPtr pnt = Marshal.AllocHGlobal(Marshal.SizeOf(uConfig));
// Copy the struct to unmanaged memory.
Marshal.StructureToPtr(uConfig, pnt, false);
// Create another UConfig.
UConfig myConfig ;
// Set this UConfig to the value of the
// UConfig in unmanaged memory.
myConfig = (UConfig)Marshal.PtrToStructure(pnt, typeof(UConfig));
However, you can no longer take advantage of the garbage collection: you've allocated unmanaged memory so you'll also have to free it! If you don't free the allocated memory you will get a memory leak, so don't roget to do this:
// Free the unmanaged memory.
Marshal.FreeHGlobal(pnt);
Upvotes: 3