|
-
January 23rd, 2013, 09:44 AM
#7
Re: A question about deleting a native pointer
Ok, let's start at the end of your post...
 Originally Posted by AKRichard
Just for clarity, I know the clr uses "gcnew" for managed objects, what I am trying to follow would be just the native use of "new" and "delete"
That's how I was already understanding it. We're talking about a native object here, and the CLR may deal with the object in several ways, including allocation and deallocation, but it may not change the nature of the object itself, because that would instantly make the object unusable on the native side, thereby spoiling the whole purpose of interop. So, as long as your native object doesn't in turn reference any managed objects, what your object fortunately doesn't, we should be able to safely ignore the CLR entirely with respect to the problem discussed here. (As a consequence, except for the plainly absurd candidates like the scripting section, ths forum section here probably is the least appropriate place for this thread. However, this sort of confusion simply can happen with interop topics and somewhat is by its nature... )
 Originally Posted by AKRichard
[...] The object is created through 3 calls to malloc, as mentioned above the first call represents the _sign pointer, the second represents the _number pointer, and the third is the one that represents the this pointer. When I built the object like this in the assembly routine and returned the created object to native/managed c++, the c++ side was reading the object fine as if it had been created with the "new" operator, giving me access not only to the internal variables (both pointers) but also to the functions and properties of the class.
The plain truth here is that an object allocated using malloc() must not be released using delete; you must use free().
I have seen quite some extensive discussions about whether, in practice, one might get away with that, or with releasing an array of objects allocated using new [] with a plain delete. The bottom line of all these discussions is that one may get away with this if the objects dealt with don't have any constructors nor destructor (not even implicitly generated ones), which is particularly true for POD objects. But that heavily depends on implementation details of both the compiler and the runtime. Of course, relying on this, frankly speaking, undefined behavior to behave in any deterministic way is big-time haphazard and better shouldn't be done at all.
In our specific scenario here, it can't even be safely expected that this implementation detail behaves consistently between the x64 and x86 versions of the MS compilers, so I can't run any meaningful (for your concrete scenario) tests here.
Of course you want your client code to be able to handle your objects as real C++ objects, using new and delete rather than malloc() and free(). I see some alternative approaches to that which all rely on your native C++ object encapsulating your assembly language implementation:
- Simply don't use malloc() to allocate the objects exposed to client code; only use new. The numeric representation arrays your object points to can be treated as implementation details which the client code isn't supposed to allocate or deallocate, so you can use malloc() and free() for them, but of course consistently. This is the simplest approach but may not easily be possible, depending on your design.
- Use the pimpl idiom and exclusively allocate/deallocate the implementation objects using malloc()/free(), just like the numeric representation arrays.
- Define a static Create() method (or some overloads of it, taking different parameters) in your native C++ class that is to be called from the assembly language routines and returns a pointer to a readily allocated and set-up object, using new of course. (Be aware of name magling, see below.) This may be one advanced way to implement option #1.
Ive been trying to find more info into the nature of the "this" pointer. Once the object I create is back in the c++ code, I have access to the various fields AND functions and properties, but in the assembly code, I only have access to the fields, which leaves me to believe that the clr/crt maps a vtable to the object somehow, but I am not sure how it associates that vtable to the object.
Instances of casses without virtual functions don't have a vtable. It's not that complicated.
I can reach the functions and properties of the native class through the assembly code, but not in the context of a particular instance of the object. This also applies to instances of the native class passed into the assembly code that were created with the "new" operator thats why I mentioned I believe it is happening in the clr/crt.
The CLR isn't involved here (see beginning of the post). It's just the way instance methods of C++ classes are called. Practically invisible at the source code level, instance methods get passed the this pointer as a hidden first parameter. That way the generated machine code inside gains access to the oject it is called on. Being aware of that, you can call instance methods from assembly language routines as well. I don't know details of how that's done in x64, but that's a pointer for further research for you.
Also, C++ uses mangled function names at the oject file level, leading to names that are somewhat obfuscated. These are the names you'd access them under from assemly language. The purpose of name mangling is to not only encode the function name itself, but also the class it's a member of and its signatore (return type and types of parameters), thereby enabling the definition of multiple overloads of a single function name. Name mangling is implementation-specific AFAIK, so I can't tell you much about how the x64 compiler handles it. Perhaps you're lucky and can find (or already have as part of your installation) a tool to convert C++ .h files to assembly language include files. That would take care of the name mangling for you, and I'm quite certain I've already seen something like that, at least for x86.
I was thrown out of college for cheating on the metaphysics exam; I looked into the soul of the boy sitting next to me.
This is a snakeskin jacket! And for me it's a symbol of my individuality, and my belief... in personal freedom.
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
|