How Hans Passant Wisheshere is my script. I have a mixed-mode application in which native code does all the hard work, while complying with performance and managed code is only responsible for the graphical interface. Also, users will participate by writing their own C # code. I have C ++ for native classes, C # for GUI and user code, and C ++ / Cli for wrapper classes between them. Among all my C ++ classes, there is one that does% 90 calculations and a different parameter is created each time. Let me call it NativeClass. There is apprx. 2000 instances of this NativeClass, and I have to find the correct instance associated with some parameter before it starts to calculate. Therefore, I developed hash_map, with parameters being a hash code, for this purpose. When I get the parameter, I look for the correct instance in hash_map,I find it and call some of its methods.
When users compete with computing by writing C # code, and this class executes these codes through callbacks. This is trivial, but sometimes I need information about the .Net classes that were created by users. So I need to somehow bind this particular ManagedClass to a NativeClass. My first solution is to use GChandle.Alloc () and move the handle address. But there are some problemsregarding GC, that he will not do his job properly. Hans recommended that Marshal.AllocCoTaskMem () and Marshal.StructureToPtr () allocate managed objects in unmanaged memory, however, I believe this is true for value type classes or structures. What about ref classes? How can I pass a link to a NativeClass without allowing them to be compiled by the GC and for the GC to work correctly over time?
Here is a sample code:
class NativeClass
{
private:
int AddressOfManagedHandle;
public:
static NativeClass * GetNativeClassFromHashMap(int SomeParameter)
{
}
NativeClass(int addr, int SomeParameter) : AddressOfManagedHandle(addr)
{
}
int GetAddress(){return AddressOfManagedHandle;}
void DoCalculation(){
}
};
public ref class ManagedClass : MarshalByRefObject
{
private:
NativeClass* _nc;
void FreeManagedClass()
{
Marshal::FreeHGlobal(IntPtr(_nc->GetAddress()));
delete _nc;
}
public:
ManagedClass()
{
IntPtr addr = (Marshal::AllocHGlobal(Marshal::Sizeof(this)));
Marshal::StructureToPtr(this,addr,true);
_nc = new NativeClass(addr.ToInt32());
}
~ManagedClass() {FreeManagedClass();}
!ManagedClass() {FreeManagedClass();}
int GetAddress() {return _nc->GetAddress();};
static ManagedClass^ GetManagedClass(int SomeParameter)
{
int addr = NativeClass::GetNativeClassFromHashMap(SomeParameter)->GetAddress();
Object^ obj = Marshal::PtrToStructure(IntPtr(addr), ManagedClass::typeid );
return dynamic_cast<ManagedClass^>(obj);
}
};
I'm sorry this toooooo is long and still not clear.
source
share