My last two posts were aimed at the integration of native types into managed classes. VC2005 does not support the use of mixed native/managed member variables in a managed class. You can have a pointer to a native type as a member variable, but you cannot declare a native type.
Thanks to some excellent work by
Brandon Brey, we've learned it is possible to have a nested class that creates an instance of the native object and exposes a pointer to that object. Brandon published a template that I have reproduced here:
template<typename>
ref class Embedded {
T* t;
!Embedded() {
if (t != nullptr) {
delete t;
t = nullptr;
}
}
~Embedded() {
this->!Embedded();
}
public:
Embedded() : t(new T) {}
static T* operator&(Embedded% e) { return e.t; }
static T* operator->(Embedded% e) { return e.t; }
};
Using Brandon's template, and some of the experimental code I presented in the last two posts, you can do some very interesting things with native structs contained in a managed class.
Let's look at some code fragments that utilize Brandon's template:
public ref class FileInformation
{
private:
// This is an embedded class that wraps our native type
Embedded<CE_FIND_DATA> fi;
...
// Operator returns a pointer to a native CE_FIND_DATA structure
static operator LPCE_FIND_DATA (FileInformation^ value)
{
// Reference the address of fi, the native object
// and cast the return to an LPCE_FIND_DATA.
return (LPCE_FIND_DATA) &(value->fi);
}
The template creates the native type in the ctor initialization and exposes a pointer to it. The operator overload method allows the class to expose a native pointer to the native class. This allows the managed class to be used in a native API call:
...
FileInformation^ finfo = gcnew FileInformation();
// This statement is why I was so interested in being able to
// use memcpy in my last post. By exposing a pointer to the
// struct definition, we can blt data in and out.
HANDLE hSearch = ::CeFindFirstFile(pFileName, (LPCE_FIND_DATA) fi);
// Access the native type member variables like this
// finfo->fi->cFileName;
...
While this is not direct compiler support of mixed native/managed member variables, it is very useful.