From: Goran on
On Jan 20, 10:51 am, w...(a)newsgroups.nospam
<weknewsgroupsnos...(a)discussions.microsoft.com> wrote:
> "Joseph M. Newcomer" wrote:
> > See below...
> > On Tue, 19 Jan 2010 02:25:01 -0800, w...(a)newsgroups.nospam
> > <weknewsgroupsnos...(a)discussions.microsoft.com> wrote:
>
> > >I have a DLL which uses MFC and is compiled with /clr (because it contains
> > >classes which must be callable from C#).
> > >That works well when being used from a C# application by calling :
> > >if (!AfxWinInit(::GetModuleHandle("<dllname>"), NULL, ::GetCommandLine(),
> > >0)) return false;
> > >AfxGetApp())->InitInstance();
> > >so that the DLL has its own App-Object/State which is initialized by the
> > >above source code.
>
> > >But now I also want to use that DLL in a C++ MFC application which already
> > >has a CWinApp object; so I would like not to establish a new one for the DLL
> > >but use the one of the MFC application.
>
> > >How can I prevent the DLL having it's own App-Object/State ?
> > ****
> > You can't.  Nor does it make sense to.  Microsoft has confused the concept of a CWinApp
> > object by reusing the same class in DLLs.  But it has no relationship to the CWinApp of
> > your app and you should not think that it does.  And in fact it could not POSSIBLY make
> > sense to use the CWinApp of the application, since the DLL can know nothing of the
> > application class.  What is it you think you need from the executable CWinApp?  Note that
> > since this is designed to run with C#, it already cannot know anything about the
> > executable that calls it, let alone anything about a CWinApp in MFC.  So how is it that it
> > can have no knowledge of a CWinApp when you call it from C# and *must* have this knowledge
> > if you call it from MFC?  Doesn't make any sense.  The DLL is a DLL..  It is not an MFC
> > Extension DLL, and it cannot share anything with its executable because it doesn't know if
> > the executable is VB, C#, or MFC.  Or, for that matter, that it was loaded and called from
> > a regular DLL or an MFC extension DLL.   I don't understand why you even think this is an
> > issue.  Perhaps the textual similarity of the name confuses you; given Microsoft chose
> > this badly, it is not surprising, but remember this: that textual name means nothing
> > outside the DLL.  It doesn't matter if it is called "CWinApp" or "DLL_Thing"; nobody
> > outside the DLL can know or care about its existence.  It does not "conflict" with the
> > executable because it cannot possibly know what the executable IS.  For "CWinApp"
> > substitute any name of your choice and you see that it has nothing to do with the
> > executable.
> >                            joe
> > ****
>
> > >Thanks in advance for any hint.
> > Joseph M. Newcomer [MVP]
> > email: newco...(a)flounder.com
> > Web:http://www.flounder.com
> > MVP Tips:http://www.flounder.com/mvp_tips.htm
> > .
>
> Hello Joseph, thanks for your posts.
>
> My problem is not that I don't want to have the AppState/CWinApp instance in
> the DLL; my problem is that I do want access to the CWinApp derived instance
> of the application because this is a very extended class with lots of
> additional properties and functionality like user authentification, database
> initialization (which is done in InitInstance of the CWinApp-derived App -
> instance) etc; the result of those operations done at startup and "stored" in
> the App-object should be accessible by my dll.
> This makes sense and works well when I use the DLL from a C# app (and in
> this case the app object is initialized in the DLL itself (see my orig.post),
> because C# apps don't have an CWinApp-object of their own). But when I have a
> C++/CLI MFC app which HAS its own CWinApp-derived instance I don't want to
> have the startup things (auth, db init etc) to be done 2 times but want to
> "reuse" the results of the C++ MFC app exe; I would only need a possibility
> to get a pointer to the native C++  app object of the EXE to that I could
> wrap it with a .NET class and then could use it in my C# assemblies.

The way you want things, you are making a cyclical module reference
(app uses dll, dll uses app). That's normally a bad idea. What you
should instead do is to move all that code into a third module and
have both exe and dll use that. See what a guy that has put a lot of
thought into these things has to say: http://butunclebob.com/ArticleS.UncleBob.PrinciplesOfOod
(in particular, look for ADP).

It is normally also a mistake to put any significant functionality in
CWinApp-derived class. I know that even MDSN samples do that, MSDN
itself might recommend it, and App-wizard does a derived class, but
it's still a bad, BAD idea. And I mean BAAAAAAD.

Think about it: WHAT do you gain by putting bunch of (often unrelated)
artifacts into CMyWinApp? You can just as well have them in separate
places and avoid any dependency to the app class. Only benefit is "one
central place to have all in". Well, that benefit is bunk. It does not
matter if you write theApp.Whatever(), or just Whatever(), or
anotherClass.Whatever(). But once your code gets bigger, your
compilation time goes up and up, because you have a lot of "Whatevers"
that don't relate much with each other.

Goran.
From: wek on
"Goran" wrote:

> On Jan 20, 10:51 am, w...(a)newsgroups.nospam
> <weknewsgroupsnos...(a)discussions.microsoft.com> wrote:
> > "Joseph M. Newcomer" wrote:
> > > See below...
> > > On Tue, 19 Jan 2010 02:25:01 -0800, w...(a)newsgroups.nospam
> > > <weknewsgroupsnos...(a)discussions.microsoft.com> wrote:
> >
> > > >I have a DLL which uses MFC and is compiled with /clr (because it contains
> > > >classes which must be callable from C#).
> > > >That works well when being used from a C# application by calling :
> > > >if (!AfxWinInit(::GetModuleHandle("<dllname>"), NULL, ::GetCommandLine(),
> > > >0)) return false;
> > > >AfxGetApp())->InitInstance();
> > > >so that the DLL has its own App-Object/State which is initialized by the
> > > >above source code.
> >
> > > >But now I also want to use that DLL in a C++ MFC application which already
> > > >has a CWinApp object; so I would like not to establish a new one for the DLL
> > > >but use the one of the MFC application.
> >
> > > >How can I prevent the DLL having it's own App-Object/State ?
> > > ****
> > > You can't. Nor does it make sense to. Microsoft has confused the concept of a CWinApp
> > > object by reusing the same class in DLLs. But it has no relationship to the CWinApp of
> > > your app and you should not think that it does. And in fact it could not POSSIBLY make
> > > sense to use the CWinApp of the application, since the DLL can know nothing of the
> > > application class. What is it you think you need from the executable CWinApp? Note that
> > > since this is designed to run with C#, it already cannot know anything about the
> > > executable that calls it, let alone anything about a CWinApp in MFC. So how is it that it
> > > can have no knowledge of a CWinApp when you call it from C# and *must* have this knowledge
> > > if you call it from MFC? Doesn't make any sense. The DLL is a DLL.. It is not an MFC
> > > Extension DLL, and it cannot share anything with its executable because it doesn't know if
> > > the executable is VB, C#, or MFC. Or, for that matter, that it was loaded and called from
> > > a regular DLL or an MFC extension DLL. I don't understand why you even think this is an
> > > issue. Perhaps the textual similarity of the name confuses you; given Microsoft chose
> > > this badly, it is not surprising, but remember this: that textual name means nothing
> > > outside the DLL. It doesn't matter if it is called "CWinApp" or "DLL_Thing"; nobody
> > > outside the DLL can know or care about its existence. It does not "conflict" with the
> > > executable because it cannot possibly know what the executable IS. For "CWinApp"
> > > substitute any name of your choice and you see that it has nothing to do with the
> > > executable.
> > > joe
> > > ****
> >
> > > >Thanks in advance for any hint.
> > > Joseph M. Newcomer [MVP]
> > > email: newco...(a)flounder.com
> > > Web:http://www.flounder.com
> > > MVP Tips:http://www.flounder.com/mvp_tips.htm
> > > .
> >
> > Hello Joseph, thanks for your posts.
> >
> > My problem is not that I don't want to have the AppState/CWinApp instance in
> > the DLL; my problem is that I do want access to the CWinApp derived instance
> > of the application because this is a very extended class with lots of
> > additional properties and functionality like user authentification, database
> > initialization (which is done in InitInstance of the CWinApp-derived App -
> > instance) etc; the result of those operations done at startup and "stored" in
> > the App-object should be accessible by my dll.
> > This makes sense and works well when I use the DLL from a C# app (and in
> > this case the app object is initialized in the DLL itself (see my orig.post),
> > because C# apps don't have an CWinApp-object of their own). But when I have a
> > C++/CLI MFC app which HAS its own CWinApp-derived instance I don't want to
> > have the startup things (auth, db init etc) to be done 2 times but want to
> > "reuse" the results of the C++ MFC app exe; I would only need a possibility
> > to get a pointer to the native C++ app object of the EXE to that I could
> > wrap it with a .NET class and then could use it in my C# assemblies.
>
> The way you want things, you are making a cyclical module reference
> (app uses dll, dll uses app). That's normally a bad idea. What you
> should instead do is to move all that code into a third module and
> have both exe and dll use that. See what a guy that has put a lot of
> thought into these things has to say: http://butunclebob.com/ArticleS.UncleBob.PrinciplesOfOod
> (in particular, look for ADP).
>
> It is normally also a mistake to put any significant functionality in
> CWinApp-derived class. I know that even MDSN samples do that, MSDN
> itself might recommend it, and App-wizard does a derived class, but
> it's still a bad, BAD idea. And I mean BAAAAAAD.
>
> Think about it: WHAT do you gain by putting bunch of (often unrelated)
> artifacts into CMyWinApp? You can just as well have them in separate
> places and avoid any dependency to the app class. Only benefit is "one
> central place to have all in". Well, that benefit is bunk. It does not
> matter if you write theApp.Whatever(), or just Whatever(), or
> anotherClass.Whatever(). But once your code gets bigger, your
> compilation time goes up and up, because you have a lot of "Whatevers"
> that don't relate much with each other.
>
> Goran.
> .
Hello Goran, thanks for your post.
I think you are right in general, BUT :
1.
The problem is that the app source exists for a long time (grown in about 15
years since MFC 1.0 ..) and is well tested ;-)
The requirement to make it accessible by .NET C# source used by the app is
very new. It's not possible to do a complete "refactoring"
2.
I think it makes sense that auth, dbinit etc. are implemented in that app
class (or in helper classes which are members of the app) and it's very
comfortable to have access to data like usernames, app-options, dbinfo etc at
every place in your MFC Source with AfxGetApp()

3
The real situation is a bit more complex; what I need is not the CWinApp *
to the derived app of the EXE; to be precise it is access to a CWinApp
derived CBaseApp which is implemented in in a base LIB which is used by
nearly 20 MFC programs which derive from this CBaseApp instead of CWinApp;
the C# DLL which is between EXE and Base LIB in hierarchy must only be able
to access the members of CBaseApp, not the derived CxxxApp objects.

Given the actual situation and requirements it would be a very elegant (in
the sense of "much benefit with little effort") solution if we simply could
access the MFC app object from C# source ..

Werner

From: Ajay Kalra on

> The problem is that the app source exists for a long time (grown in about 15
> years since MFC 1.0 ..) and is well tested ;-)

Why does a C# app need CWinapp object/functionality from MFC? I would
expose exactly and only what is needed by clients, C# or not, without
even letting them know that CWinApp object exists. Expose the
functionality instead of the object.

--
Ajay

From: Joseph M. Newcomer on
An extension DLL is a concept normally applied to native code. If you have a DLL compiled
with /clr, and you are calling it from MFC code, then the MFC code has to be prepared to
handle CLR-style objects. But the concept of CWinApp is not relevant here. There might
be a thing derived from "CWinApp" in your DLL, but any impression that it has anything at
all to do with the thing called "CWinApp" in the application is mistaken.
joe

On Wed, 20 Jan 2010 01:36:01 -0800, wek(a)newsgroups.nospam
<weknewsgroupsnospam(a)discussions.microsoft.com> wrote:

>"Ajay Kalra" wrote:
>
>> On Jan 19, 5:25 am, w...(a)newsgroups.nospam
>> <weknewsgroupsnos...(a)discussions.microsoft.com> wrote:
>> > I have a DLL which uses MFC and is compiled with /clr (because it contains
>> > classes which must be callable from C#).
>> > That works well when being used from a C# application by calling :
>> > if (!AfxWinInit(::GetModuleHandle("<dllname>"), NULL, ::GetCommandLine(),
>> > 0)) return false;
>> > AfxGetApp())->InitInstance();
>> > so that the DLL has its own App-Object/State which is initialized by the
>> > above source code.
>> >
>> > But now I also want to use that DLL in a C++ MFC application which already
>> > has a CWinApp object; so I would like not to establish a new one for the DLL
>> > but use the one of the MFC application.
>> >
>> > How can I prevent the DLL having it's own App-Object/State ?
>>
>> You cant prevent it. However you can switch states using
>> AFX_MANAGE_STATE macros. Also, the scenario you pointed out would be
>> present in a Regular MFC dll and not in a MFC Extension DLL. Any
>> reason to have a regular DLL as opposed to an MFC Extension DLL?
>>
>> --
>> Ajay
>>
>> .
>Hello Ajay, thanks for your help.
>My DLL (.NET) exposes .NET classes and must be accessible from anonther .NET
>DLL written in C#. My EXE is written in C++, uses MFC and is compiled with
>/clr.
>http://msdn.microsoft.com/en-us/library/h5f7ck28(VS.80).aspx says :
>"An extension DLL can also be used by a regular DLL that is dynamically
>linked to MFC.", but my C# DLL is not linked to MFC, only the EXE is.
>So I think I can't use a MFC extension DLL; or am I wrong with this ?
>
>Werner
Joseph M. Newcomer [MVP]
email: newcomer(a)flounder.com
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm
From: Goran on
On Jan 20, 1:56 pm, w...(a)newsgroups.nospam
<weknewsgroupsnos...(a)discussions.microsoft.com> wrote:
> "Goran" wrote:
> Hello Goran, thanks for your post.
> I think you are right in general, BUT :
> 1.
> The problem is that the app source exists for a long time (grown in about 15
> years since MFC 1.0 ..) and is well tested ;-)
> The requirement to make it accessible by .NET C# source used by the app is
> very new. It's not possible to do a complete "refactoring"  

Ok, so in fact you already have a (legacy) application. I don't see
where does the DLL come from. Did you just started writing a DLL with
the requirement to access the app from .NET? If so, I would suggest
you drop the idea, and go with COM, the most standard Windows app
interoperability approach. Did you consider that?

> 2.
> I think it makes sense that auth, dbinit etc. are implemented in that app
> class (or in helper classes which are members of the app) and it's very
> comfortable to have access to data like usernames, app-options, dbinfo etc at
> every place in your MFC Source with AfxGetApp()

No, you did not think that through. It's not comfortable. In reality,
the code that uses auth/dbinit "services" has to do e.g. the
following:

#include "MyApp.h"
....
static_cast<CMyApp*>(AfxGetApp())->auth();
// In fact, if your team was any smart,
// that should have become theApp.auth()
// at some point

So why do you want to pull CWinApp into a piece of code that uses only
"custom" functionality? There's no reason! I know, I've been doing it
for years before dropping the idea. It's stupid, and I am sure that
others here will tell you the same.

Instead, your code could have had, for example, this:

#include "auth.h"
....
auth()
//or
someProbablyStaticObj.Auth();

And if same piece of code uses something from CWinApp, then AfxGetApp
() is OK, you just go e.g.:

AfxGetApp()->AddDocTemplate();

(No additional #include needed, because stdafx.h includes afxwin.h)

In other words, there is NO benefit to putting e.g. "auth" in the app
class. There is (I am repeating myself here), an inconvenience of
creating random compile time dependencies. If your code has been
developed, as you say, for 20 years, then consider this: if you change
smallest of things in your CBaseApp, that triggers massive, and I mean
MASSIVE, recompilation cycle. Just think how much time has been lost
waiting for this compilation over the years. All because your
colleagues put all their eggs in one basket, so to speak.

> 3
> The real situation is a bit more complex; what I need is not the CWinApp *
> to the derived app of the EXE; to be precise it is access to a CWinApp
> derived CBaseApp which is implemented in in a base LIB which is used by
> nearly 20 MFC programs which derive from this CBaseApp instead of CWinApp;
> the C# DLL which is between EXE and Base LIB in hierarchy must only be able
> to access the members of CBaseApp, not the derived CxxxApp objects.

> Given the actual situation and requirements it would be a very elegant (in
> the sense of "much benefit with little effort") solution if we simply could
> access the MFC app object from C# source ..

Accessing native C++ code from C# is AFAIK not possible. What should
be possible, is to write C++/CLI wrapper library for your base
library. That is similar to creating COM wrapper for your application,
but the wrapper is pure .NET code. That would be the best approach
then (better than COM, because you really only seem to be interested
in base LIB functionality, so no executable module is needed).

Goran.