From: mk on
Hello,

I am working at an application that has the following (admittedly somewhat
strange) module architecture:
* Application "A" dynamically loads my regular Unicode MFC DLL "R"
(presumably by using LoadLibraryA)
* "R" statically loads my unicode extension dll "E"
* "E" itself statically loads two MBCS extension dlls written by a external
vendor.

Unfortunately, my regular DLL "R" (and hence, the two extension) cannot be
loaded by the application.

Now the questions: Is my model architecture generally feasible? Might the
root of the problem be that "R" and "E" use the MFC90UD.DLL whereas the
external extension dlls use "MFC90D.DLL"?

Thanks mk
From: David Lowndes on
>Unfortunately, my regular DLL "R" (and hence, the two extension) cannot be
>loaded by the application.

Why not? Have you used Depends to check if all necessary DLLs are
present?

>Now the questions: Is my model architecture generally feasible?

I don't see any immediate reason why it shouldn't - but we've really
only got a tiny bit of the picture.

> Might the
>root of the problem be that "R" and "E" use the MFC90UD.DLL whereas the
>external extension dlls use "MFC90D.DLL"?

For a release product none should require the "D" (debug) versions -
however I think the direct answer to your question is that it (of
itself) shouldn't be an issue.

Dave
From: Ajay Kalra on
On Feb 9, 11:57 am, mk <m...(a)discussions.microsoft.com> wrote:
> Hello,
>
> I am working at an application that has the following (admittedly somewhat
> strange) module architecture:
> * Application "A" dynamically loads my regular Unicode MFC DLL "R"
> (presumably by using LoadLibraryA)
> * "R" statically loads my unicode extension dll "E"
> * "E" itself statically loads two MBCS extension dlls written by a external
> vendor.
>
> Unfortunately, my regular DLL "R" (and hence, the two extension) cannot be
> loaded by the application.
>
> Now the questions: Is my model architecture generally feasible? Might the
> root of the problem be that "R" and "E" use the MFC90UD.DLL whereas the
> external extension dlls use  "MFC90D.DLL"?
>
> Thanks mk

Your entire process should have one MFC dll, either go with 90UD or
90D. Why do you need to mix?
Also, why do you need R to be not an extension DLL?

If you are limited by external vendors linking to a different version
of MFC than you do, you have only two choices: have a different
version of your app which matches the external vendors app or get
external vendors libs with the version that you are using. With
Extension DLLs you are going to have issues immediately if different
version of MFCs are used in the same process(For starters,
AfxGetMainWnd would be different for each versrion).

--
Ajay
From: Joseph M. Newcomer on
See below...
On Tue, 9 Feb 2010 08:57:01 -0800, mk <mk(a)discussions.microsoft.com> wrote:

>Hello,
>
>I am working at an application that has the following (admittedly somewhat
>strange) module architecture:
>* Application "A" dynamically loads my regular Unicode MFC DLL "R"
>(presumably by using LoadLibraryA)
****
Well, I would expect it to use LoadLibrary. It will call LoadLibraryA if it is an ANSI
(8-bit character app) and LoadLibraryW if it is a Unicode app. You did not say what kind
of app it is.
****
>* "R" statically loads my unicode extension dll "E"
****
I have no idea what "statically loads" means for a DLL. Did you mean "implicitly loads"?
Static loading of a library is what happens when you directly link a .lib file into an
executable image.

Note this is an odd sequence, to load an extension DLL from a regular DLL. Also, there
are serious issues here. If the executable is an ANSI app, and you load a Unicode
extension DLL, you are begging for disaster to strike. This is because you will end up
with two completely different, and incompatible, copies of the MFC runtime, one for the
executable and one for the extension DLL E
****
>* "E" itself statically loads two MBCS extension dlls written by a external
>vendor.
****
Again, I assume you meant to say "implicitly loads". And here you have another disaster
scenario. An 8-bit extension DLL will load the 8-bit version of the MFC library; you have
a different version loaded for your extension DLL "E", and this might be different from
the executable.

This is a scenario that, instead of asking "why doesn't it work?", I'm more inclined to
ask "How could it possibly work?"
****
>
>Unfortunately, my regular DLL "R" (and hence, the two extension) cannot be
>loaded by the application.
****
This is a meaningless statement. If it "cannot be loaded", there are error messages
issued, or error codes returned. Without knowing what this vague handwave of "cannot be
loaded" means, that is, WHAT IS SEEN TO OCCUR, IN DETAIL, I will have to find my old
crystal ball and dust it off, and I don't feel like doing that right now.
****
>
>Now the questions: Is my model architecture generally feasible? Might the
>root of the problem be that "R" and "E" use the MFC90UD.DLL whereas the
>external extension dlls use "MFC90D.DLL"?
****
Absolutely. As I said, I would expect that this would fail in some interesting fashion,
but I would be incredibly surprised if it worked at all. You really can't mix MFC
runtimes like this. Each DLL tries to maintain an image of what is going on, and the
images will conflict. Not a feasible solution. You will have to figure out how to make
this work in some other fashion, such as acquiring updated DLLs from the third party, or
reverting everything to ANSI/MBCS. But on the whole, I think the current configuration is
doomed to never work.
joe
****
>
>Thanks mk
Joseph M. Newcomer [MVP]
email: newcomer(a)flounder.com
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm
From: mk on
Hi Joe,

thank you for your answer.

> You did not say what kind of app it is.
Well, it is also an application of an external vendor. It can be extended by
registering plug-in dlls which then are loaded at startup. It's definitely an
ANSI application. But it's not specified whether the plug-ins are loaded via
AfxLoadLibrary or via the Win32 LoadLibrary.

> I have no idea what "statically loads" means for a DLL. Did you mean "implicitly loads"?
Sorry. I indeed meant "implicitly".

> If the executable is an ANSI app, and you load a Unicode extension DLL, you are
> begging for disaster to strike. This is because you will end up
> with two completely different, and incompatible, copies of the MFC runtime, one for the
> executable and one for the extension DLL E
I'm not calling the extension dll directly from the application. I'm aware,
that an extension dll and its client application have to use the same version
of MFCxx.dll. But I thought the CWinApp-derived object in my regular dll
would act as client and hence would decouple the extension dll from the
application.

> And here you have another disaster scenario. An 8-bit extension DLL will load
> the 8-bit version of the MFC library; you have a different version loaded for
> your extension DLL "E", and this might be different from the executable.
> This is a scenario that, instead of asking "why doesn't it work?", I'm more inclined to
> ask "How could it possibly work?"
I'm not familiar with the MFC internals. Accordingly, wasn't quite sure
whether the 8-bit and the unicode MFC libraries are compatible. But from my
point of view, there is no reason why the two runtimes of the same version
shouldn't be able to interact.

> This is a meaningless statement. If it "cannot be loaded", there are error messages
> issued, or error codes returned. Without knowing what this vague handwave of "cannot be
> loaded" means, that is, WHAT IS SEEN TO OCCUR, IN DETAIL, I will have to find my old
> crystal ball and dust it off, and I don't feel like doing that right now.
Unfortunately, that's my problem as well. The error occurs while the dll is
loaded. So there are neither error messages nor error codes. I only obtain a
first chance exception in the ntdll.dll.
The debugger's output is as follows. Where "NpcDlabQslrD.dll" is the reguar
dll "R". "NpcDlabQslrUxD.dll" is my extension dll "E". "edaq.dll" and
"logger.dll" are the external 8-bit extension dlls.

'DASYLAB.EXE': Loaded 'D:\Dlab90\NpcDlabQslrD.dll', Symbols loaded.
'DASYLAB.EXE': Loaded 'D:\Dlab90\NpcDlabQslrUxD.dll', Symbols loaded.
'DASYLAB.EXE': Loaded 'D:\Dlab90\eDaq.dll'
'DASYLAB.EXE': Loaded 'D:\Dlab90\Logger.dll'
'DASYLAB.EXE': Loaded 'C:\WINDOWS\system32\MFC42D.DLL', Symbols loaded.
'DASYLAB.EXE': Loaded 'C:\WINDOWS\system32\MSVCRTD.DLL', Symbols loaded.
'DASYLAB.EXE': Loaded 'C:\WINDOWS\system32\MSVCP60D.DLL', Symbols loaded.
'DASYLAB.EXE': Loaded 'C:\WINDOWS\system32\MFCN42D.DLL', Symbols loaded.
First-chance exception at 0x7c9766c6 in DASYLAB.EXE: 0xC0000138: Ordinal Not
Found.

> Absolutely. As I said, I would expect that this would fail in some interesting fashion,
> but I would be incredibly surprised if it worked at all. You really can't mix MFC
> runtimes like this. Each DLL tries to maintain an image of what is going on, and the
> images will conflict. Not a feasible solution.
The thing is that I tested this architecture before we implemented it and
everything worked out fine. For days, I'm trying to build test binaries that
cause this error. But I can't reproduce it. Hence, this architecture seems to
work for most configurations.

> You will have to figure out how to make
> this work in some other fashion, such as acquiring updated DLLs from the third party, or
> reverting everything to ANSI/MBCS. But on the whole, I think the current configuration is
> doomed to never work.
Provided I could persuade the vendor of the ansi extension dlls to build a
unicode version, would the module dependencies would look like this:
Ansi exe -> regular dll unicode -> ext dll Unicode -> ext dll unicode.

Is this constellation officially supported by MFC?

Thanks, mk