B
Bob Altman
I need some education on something that is apparently so basic that it's not
described anywhere in the MSDN docs (that I can find).
Here is the underlying problem I am trying to solve: I have two existing
products. One is a managed code product that includes a singleton (exposed by
..Net remoting) written in VB.Net. The other is an unmanaged DLL written in C++.
I need to add some functions to the native DLL that call into the managed
singleton.
I've managed to figure out a few of the basics involved in this sort of
native-to-managed interop, but I'm confused on several points. Here's what I
think I know:
1. I can control which of my C++ source files compile to native or managed code
by fiddling with the /clr option (and a bunch of other options that conflict
with /clr) for the managed code files.
2. I can directly call a managed function from unmanaged code by way of C++/CLI
magic and things that go thunk in the night...
3. I can (or can't?) hold a reference to managed objects in my unmanaged code.
Here's where things start getting very fuzzy for me. I looked at the docs for
gcroot, which "wraps GCHandle, to hold a CLR object reference in unmanaged
memory". That sounds promising, but the template parameter used to declare a
gcroot reference looks like a managed object reference. I have no idea how to
reference such a thing from my native code, which doesn't know anything about
managed namespaces. To further confuse me, the example code looks like this:
#pragma managed
class StringWrapper {
private:
gcroot<String^> s;
public:
void PrintString() {...}
};
#pragma unmanaged
int main() {
// Create a StringWrapper instance on the unmanaged stack???
StringWrapper s;
s.PrintString();
}
As near as I can tell, the gcroot and its internal GCHandle are there for no
reason other than to prevent the GC from destroying the managed string object
because, in this example, the only reference to the managed string comes from
the unmanaged code that is holding a reference to StringWrapper, which, in turn,
is holding the String object. Is this correct?
The part of this that confuses the heck out of me is this: How is it that the
unmanaged code can create a presumably managed StringWrapper class instance?
Does the C++/CLI magic let me create managed objects on the unmanaged stack even
though I can't hold a reference to one created on the heap?
TIA - Bob
described anywhere in the MSDN docs (that I can find).
Here is the underlying problem I am trying to solve: I have two existing
products. One is a managed code product that includes a singleton (exposed by
..Net remoting) written in VB.Net. The other is an unmanaged DLL written in C++.
I need to add some functions to the native DLL that call into the managed
singleton.
I've managed to figure out a few of the basics involved in this sort of
native-to-managed interop, but I'm confused on several points. Here's what I
think I know:
1. I can control which of my C++ source files compile to native or managed code
by fiddling with the /clr option (and a bunch of other options that conflict
with /clr) for the managed code files.
2. I can directly call a managed function from unmanaged code by way of C++/CLI
magic and things that go thunk in the night...
3. I can (or can't?) hold a reference to managed objects in my unmanaged code.
Here's where things start getting very fuzzy for me. I looked at the docs for
gcroot, which "wraps GCHandle, to hold a CLR object reference in unmanaged
memory". That sounds promising, but the template parameter used to declare a
gcroot reference looks like a managed object reference. I have no idea how to
reference such a thing from my native code, which doesn't know anything about
managed namespaces. To further confuse me, the example code looks like this:
#pragma managed
class StringWrapper {
private:
gcroot<String^> s;
public:
void PrintString() {...}
};
#pragma unmanaged
int main() {
// Create a StringWrapper instance on the unmanaged stack???
StringWrapper s;
s.PrintString();
}
As near as I can tell, the gcroot and its internal GCHandle are there for no
reason other than to prevent the GC from destroying the managed string object
because, in this example, the only reference to the managed string comes from
the unmanaged code that is holding a reference to StringWrapper, which, in turn,
is holding the String object. Is this correct?
The part of this that confuses the heck out of me is this: How is it that the
unmanaged code can create a presumably managed StringWrapper class instance?
Does the C++/CLI magic let me create managed objects on the unmanaged stack even
though I can't hold a reference to one created on the heap?
TIA - Bob