By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
425,854 Members | 869 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 425,854 IT Pros & Developers. It's quick & easy.

warning C4251 using gcroot<> accross multiple native dlls

P: n/a
Hello,

I have a class hierarchy distributed over 3 native C++ dlls. The base class
has a .NET Windows.Form for status output via a gcroot<>.
The gcroot is declared private - the sub classes only have access via a
protected "print"-method.
I need the different dlls as the sub classes implement the base class's pure
virtual methods using different technologies.
To use the native classes from outside their dlls I use the
__declspec(dllexport) marco. This all works without any runtime error.

Still when the sub classes' dlls are compiled I get the following warning
(for each sub class):

warning C4251: 'UnmanagedComponent::m_pFormDebugOutput' : struct 'gcroot<T>'
needs to have dll-interface to be used by clients of class
'UnmanagedComponent'

where "UnmanagedComponent" is my base class and "m_pFormDebugOutput" is the
"private"-declared gcroot<of type Windows.Forms.Form.

What does this warning mean in this respect? Is there a solution to get rid
of it (apart from switching it off)?

Thanks a lot in advance. Regards,

Fabian
Nov 21 '07 #1
Share this Question
Share on Google+
6 Replies


P: n/a
The warning doesn't matter unless some inline member function of
UnmanagedComponent (or its derived classes) uses pFormDebugOutput in some way
other than a simple pointer reference. If it is the case (access member
functions through the pointer) you have to export gcroot<>

IMO the best solution is to use the pimpl idiom to get rid of private members
from the interface definition.

Regards

--
Cholo Lennon
Bs.As.
ARG
"Fabian" <Fa****@discussions.microsoft.comwrote in message
news:39**********************************@microsof t.com...
Hello,

I have a class hierarchy distributed over 3 native C++ dlls. The base class
has a .NET Windows.Form for status output via a gcroot<>.
The gcroot is declared private - the sub classes only have access via a
protected "print"-method.
I need the different dlls as the sub classes implement the base class's pure
virtual methods using different technologies.
To use the native classes from outside their dlls I use the
__declspec(dllexport) marco. This all works without any runtime error.

Still when the sub classes' dlls are compiled I get the following warning
(for each sub class):

warning C4251: 'UnmanagedComponent::m_pFormDebugOutput' : struct 'gcroot<T>'
needs to have dll-interface to be used by clients of class
'UnmanagedComponent'

where "UnmanagedComponent" is my base class and "m_pFormDebugOutput" is the
"private"-declared gcroot<of type Windows.Forms.Form.

What does this warning mean in this respect? Is there a solution to get rid
of it (apart from switching it off)?

Thanks a lot in advance. Regards,

Fabian

Nov 21 '07 #2

P: n/a
Hi Cholo,
If it is the case (access member functions through the pointer) you have to export gcroot<>
How would I do this in this case?

__declspec(dllexport) gcroot<FormDebugOutput^>;

in the header file makes the compiler produce the following message:

warning C4091: '__declspec(dllexport)' : ignored on left of 'gcroot<T>' when
no variable is declared
IMO the best solution is to use the pimpl idiom to get rid of private members
from the interface definition.
How much performance would this additional redirection cost? My design
already is performance consuming: Calling into the gcroot<should take at
least one context switch.

Thanks a lot for your help,

Fabian

Nov 22 '07 #3

P: n/a
How would I do this in this case?
>
__declspec(dllexport) gcroot<FormDebugOutput^>;

in the header file makes the compiler produce the following message:

warning C4091: '__declspec(dllexport)' : ignored on left of 'gcroot<T>' when
no variable is declared
To view an example of how to export a template take a look to:
http://support.microsoft.com/?scid=k...8958&x=12&y=10

The problem with dllexport is that it's incompatible with __clrcall convention
(used by clr objects) :-( so you cannot export a template with clr types (I
didn't know it until today). If you don't have inline functions that use use
gcroot<simply get rid the warning with #pragma or use pimpl idiom (or redesign
your classes to provide an interface based in abstract classes).
>
IMO the best solution is to use the pimpl idiom to get rid of private
members
from the interface definition.

How much performance would this additional redirection cost? My design
already is performance consuming: Calling into the gcroot<should take at
least one context switch.
It's depends of how you implement the pimpl idiom. If you use a raw pointer or
boost::scoped_ptr, the penalty is minimum (almost nothing; the compiler adds
only one instruction). If you use boost::shared_ptr the penalty increase. Just
take a look the generated asm code using a raw pointer:

class Foo {
...
void pimplCall();
void directCall();

ToCall m_toCall;

struct Impl;
Impl* m_pImpl;
...
};

struct Foo::Impl {
ToCall m_toCall;
};

pImpl call: m_pImpl->m_toCall.Test();
00401057 mov eax,dword ptr [this]
0040105A mov ecx,dword ptr [eax+4]
0040105D call ToCall::Test (401000h)

Direct call: m_toCall.Test();
00401077 mov ecx,dword ptr [this]
0040107A call ToCall::Test (401000h)
Regards

PS: [boost] Remember that If your class is non copyable you can use
boost::scoped_ptr. If your class is copyable you have to use boost::shared_ptr
--
Cholo Lennon
Bs.As.
ARG

Nov 22 '07 #4

P: n/a
Hi Cholo,
The problem with dllexport is that it's incompatible with __clrcall convention
(used by clr objects) :-( so you cannot export a template with clr types (I
didn't know it until today).
If you create a pure win32 dll with the VS wizard it has __stdcall
convention. Compiled with /clr you get a dll which can both use clr objects
via a gcroot<and export native classes that use a gcroot.
But then we're back to the beginning: The class export works, but the
compiler complains about the non-exported gcroot member.

thanks a lot for your help,

Fabian
Nov 23 '07 #5

P: n/a
Maybe this can help:

http://msdn.microsoft.com/msdnmag/issues/06/06/CAtWork/
http://www.thescripts.com/forum/thread285515.html

Regards
--
Cholo Lennon
Bs.As.
ARG
"Fabian" <Fa****@discussions.microsoft.comwrote in message
news:11**********************************@microsof t.com...
Hi Cholo,
The problem with dllexport is that it's incompatible with __clrcall
convention
(used by clr objects) :-( so you cannot export a template with clr types
(I
didn't know it until today).

If you create a pure win32 dll with the VS wizard it has __stdcall
convention. Compiled with /clr you get a dll which can both use clr objects
via a gcroot<and export native classes that use a gcroot.
But then we're back to the beginning: The class export works, but the
compiler complains about the non-exported gcroot member.

thanks a lot for your help,

Fabian

Nov 23 '07 #6

P: n/a

"Fabian" <Fa****@discussions.microsoft.comwrote in message
news:D6**********************************@microsof t.com...
Hi Cholo,
>If it is the case (access member functions through the pointer) you have
to export gcroot<>

How would I do this in this case?

__declspec(dllexport) gcroot<FormDebugOutput^>;

in the header file makes the compiler produce the following message:

warning C4091: '__declspec(dllexport)' : ignored on left of 'gcroot<T>'
when
no variable is declared
>IMO the best solution is to use the pimpl idiom to get rid of private
members
from the interface definition.

How much performance would this additional redirection cost? My design
already is performance consuming: Calling into the gcroot<should take at
least one context switch.
gcroot should not cause a context switch unless combined with Remoting.

pimpl's performance cost is a tiny fraction of a context switch, maybe
1/1000.
>
Thanks a lot for your help,

Fabian
Nov 23 '07 #7

This discussion thread is closed

Replies have been disabled for this discussion.