
Signature
This posting is provided "AS IS" with no warranties, and confers no
rights."Use of included script samples are subject to the terms specified at
http://www.microsoft.com/info/cpyright.htm"
> Dear VS Team,
>
[quoted text clipped - 76 lines]
>
> Martin Zenkel
Thanks for the very clear post. We do allow a managed class to have a
function returning a pointer to an unmanaged class. The only thing
disallowed is embedding native
types in managed types. You are missing __declspec(dllexport) and
__declspec(dllimport) on your class declarations. I have copied the correct
working code.
cl /EHsc /LD native.cpp
cl /clr m.cpp /link native.lib
///////////////// native.cpp
struct __declspec(dllexport) A
{
int data;
};
///////////////// m.cpp
using namespace System;
struct __declspec(dllimport) A
{
int data;
};
public ref class B
{
public:
A* a;
B()
{
a = new A();
a->data = 4;
}
A* get() // returning a pointer to a native struct.
{
return a;
}
};
int main()
{
B obj;
A* a = obj.get();
Console::WriteLine(a->data);
}
Does that help?
Thanks,
Kapil
Tamas Demjen - 04 May 2005 02:53 GMT
I think Martin meant that a managed dll can't export an unmanaged member
pointer, such as:
///////////////// native.h (a native DLL project)
struct __declspec(dllexport) A
{
int data;
};
///////////////// managed1.h (a managed DLL project)
struct __declspec(dllimport) A
{
int data;
};
public ref class B
{
public:
B()
{
a = new A();
a->data = 4;
}
A* get() // returning a pointer to a native struct.
{
return a;
}
private:
A* a;
};
///////////////// managed2.h (another managed .exe or DLL project)
#using "managed1.dll"
void test()
{
B b;
b.get(); // error: 'B::get' candidate function(s) not accessible
}
So a managed assembly (DLL) doesn't seem to be able to export unmanaged
pointers. There are two choices:
1. You either #include "managed1.h" and add managed1.cpp to the second
project, and then get() is accessible and is working, or
2. you are #using "managed1.dll" and the get() function simply can't be
called. I couldn't mix #using and #include.
Sometimes it would be nice to have access from one assembly to unmanaged
members in another assembly. Just like Graphics::GetHdc(), which returns
the underlying HDC handle. Similarly, it would be nice to add a get()
function to my managed classes that wrap an underlying native C/C++ API.
Sometimes it's inevitable, that's why WinForms has GetHdc too. As I see
it, Graphics::GetHdc returns a managed type called IntPtr, so that's how
it works internally. I don't think a managed assembly is able to return
pointers to unmanaged C++ types, but if it's possible, I would really
like to know how.
Perhaps returning IntPtr and casting it to our native C++ type is the
only way. I actually tried it and it worked:
///////////////// managed1.h
public ref class B
{
[...]
IntPtr get() { return static_cast<IntPtr>(a); }
[...]
};
///////////////// managed2.h
A* a = reinterpret_cast<A*>(static_cast<void*>(b.get()));
This is a little bit nasty, in my opinion, if it's correct at all. I
wish there was a more user friendly way of doing this, with better
unmanaged type safety.
Any comments? I'm still in the early experimenting phase with Beta 2.
Tom