-
February 19th, 2007, 10:17 AM
#1
Reflection - Assembly::CreateInstance of a non "ref" c++ class
Hello All.
I have a c++ class not defined with the ref keyword
class CMsg {...}
I'm trying to create an instance of CMsg using Reflection, as follows:
Assembly^ assembly = Assembly::GetAssembly(CMsg::typeid);
System::Object^ msg = assembly->CreateInstance("SIMsgs.CMsg");
Well, it works, I get a CMsg, but as a _reference_, while I need a pointer....
Since CMsg is not a "ref" class I can't cast the return value to CMsg, and so can't call its methods. I can see it's member in the debugger, but can't reach them.
For example this line:
CMsg ^cmsg = (CMsg ^)msg;
Create the following complication errors:
Error 1 error C3699: '^' : cannot use this indirection on type 'SIMsgs::CMsg' e:\projects\Secure1\pkg\Server\SIMsgs\MsgGenerator.cpp 34
Error 2 error C3699: '^' : cannot use this indirection on type 'SIMsgs::CMsg' e:\projects\Secure1\pkg\Server\SIMsgs\MsgGenerator.cpp 34
Error 3 error C2440: 'type cast' : cannot convert from 'System::Object ^' to 'SIMsgs::CMsg *' e:\projects\Secure1\pkg\Server\SIMsgs\MsgGenerator.cpp 34
Anyway to get a (CMsg *) out of the return value of CreateInstance()?
Any other solution?
Thank you very much and in advance,
Roee Oz
-
February 20th, 2007, 04:26 AM
#2
Re: Reflection - Assembly::CreateInstance of a non "ref" c++ class
If a class isn't managed, you can't use reflection on it. What you're getting is strange behaviour : but I really, really wouldn't go any further with this without making the class managed.
Darwen.
-
February 20th, 2007, 08:30 AM
#3
Re: Reflection - Assembly::CreateInstance of a non "ref" c++ class
Thanks for your answer. I already converted the code not to use reflection, but I would still want to understand better what happens here since my application mixing managed and unmanged code as well as C# and C++. As so I would like to improve my understanding of the CreateInstance mechanisem, reference types, pointer types and so on.
I'll still be glad if someone can explain this funny behavior (CreateInstance() initialize a non managed class as a reference, which I can't use)
Roee
-
February 20th, 2007, 08:39 AM
#4
Re: Reflection - Assembly::CreateInstance of a non "ref" c++ class
Chances are that you have some managed code inside of your native class. This creates a kind of hybrid : it's not a real managed class, it's sort of half managed.
I've noticed this sort of behaviour before and it is rather peculiar. I've never gone into the exact mechanisms behind it : let's face it you shouldn't be doing it anyway.
What's probably happening is that a managed wrapper around the native class is being created when you call CreateInstance(). Probably the same sort of thing as the COM mechanism (CCW/RCWs).
Darwen.
-
February 20th, 2007, 08:53 AM
#5
Re: Reflection - Assembly::CreateInstance of a non "ref" c++ class
I've just tried this :
Code:
#include "stdafx.h"
using namespace System;
using namespace System::Reflection;
using namespace System::Runtime::InteropServices;
class CMyClass
{
public:
CMyClass()
{
m_nData = 100;
System::Diagnostics::Debug::WriteLine("Constructed");
}
void Trace()
{
System::Diagnostics::Debug::WriteLine("Trace"));
}
private:
int m_nData;
} ;
int main(array<System::String ^> ^args)
{
Assembly ^assembly = Assembly::GetExecutingAssembly();
Object ^obj = assembly->CreateInstance("CMyClass");
System::Diagnostics::Debug::WriteLine(obj->GetType());
GCHandle handle = System::Runtime::InteropServices::GCHandle::Alloc(obj, GCHandleType::Pinned);
CMyClass *pMyClass = reinterpret_cast<CMyClass *>(handle.AddrOfPinnedObject().ToPointer());
pMyClass->Trace();
handle.Free();
return 0;
}
It appears that the memory for the class is being allocated, but the constructor isn't being called. After pinning the memory and recasting you can make method calls to the class, but this could just be luck.
Darwen.
Last edited by darwen; February 20th, 2007 at 08:59 AM.
-
February 20th, 2007, 08:58 AM
#6
Re: Reflection - Assembly::CreateInstance of a non "ref" c++ class
Ah ha ! How's this for an explanation :
The C++ class is being defined as an empty managed structure, but with the size of the structure defined as the size of the C++ class (therefore the memory is being allocated correctly).
If you use Lutz Roeder's .NET reflector to look at the class then you'll see it's being defined as :
Code:
[StructLayout(LayoutKind.Sequential, Size=4), NativeCppClass, DebugInfoInPDB, MiscellaneousBits(0x40)]
internal struct CMyClass
{
}
So the metadata for creating the memory for the class exists, but not the metadata of the methods/properties/fields etc of the class.
Darwen.
Last edited by darwen; February 20th, 2007 at 09:01 AM.
-
June 27th, 2007, 08:22 AM
#7
Re: Reflection - Assembly::CreateInstance of a non "ref" c++ class
Hay, didn't monitor this thread for a while.
Great answer and explanation, thanks a lot.
I didn't look at it since the "Just Don't Do It" discussion.
Thanks again for the explanations.
Roee
-
September 1st, 2022, 09:02 AM
#8
Re: Reflection - Assembly::CreateInstance of a non "ref" c++ class
 Originally Posted by darwen
Ah ha ! How's this for an explanation :
The C++ class is being defined as an empty managed structure, but with the size of the structure defined as the size of the C++ class (therefore the memory is being allocated correctly).
So the metadata for creating the memory for the class exists, but not the metadata of the methods/properties/fields etc of the class.
Darwen.
Exactly correct. You can then use "placement new" to actually create the native object inside that space 
The use-cases where this is a desirable approach are pretty slim, but are NOT zero.....
Just think of it as another custom allocator mechanism (something C++ heavily supports!)
TheCPUWizard is a registered trademark, all rights reserved. (If this post was helpful, please RATE it!)
2008, 2009,2010
In theory, there is no difference between theory and practice; in practice there is.
* Join the fight, refuse to respond to posts that contain code outside of [code] ... [/code] tags. See here for instructions 
* How NOT to post a question here
* Of course you read this carefully before you posted
* Need homework help? Read this first
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|