c++/CLI mixed mode dlls and clr initialisation

B

bonk

I have a plain unmanaged exe (no /CLR) that is supposed to to use classes
from a mixed mode dll (dll that uses .NET internally). That dll only needs
to expose unmanaged interfaces (classes and/or functions). This is of course
no problem and it works fine. However I have the special scenario where the
exe needs to be able to run even when there is no .NET Framework installed.
The exe is supposed to check at runtime if the .NET Framework is available
(in its correct version) and only in that case it will use classes/functions
from that dll.

As long as I link at runtime (via Loadlibrary()) this works fine. I obtain
processadress of an exportet function wich then delivers me a pointer to an
instance of some interface class. If that fails I know .net is not
available. Correct ?

But what if I wanted to use classes ( class __declspec( dllexport )
MyUnmanagedClassWichUsesNETInternally ) that are exportet in that dll. I
suppose that would require compiletime linking (if that is the correct term
....) with a .lib and a .h ? Do you see any way to expose classes in my
mixed mode dll and use them in my unmanaged exe AND still be able to run
that exe even if there is no .NET Framework available.
The exe would just need to check if it is availbale and only then "use" that
dll. This would somehow require that the CLR only gets initialized when the
dll is "touched".

I hope this make at least a little bit sense .....
 
C

Carl Daniel [VC++ MVP]

bonk said:
I have a plain unmanaged exe (no /CLR) that is supposed to to use classes
from a mixed mode dll (dll that uses .NET internally). That dll only needs
to expose unmanaged interfaces (classes and/or functions). This is of
course
no problem and it works fine. However I have the special scenario where
the
exe needs to be able to run even when there is no .NET Framework
installed.
The exe is supposed to check at runtime if the .NET Framework is available
(in its correct version) and only in that case it will use
classes/functions
from that dll.

As long as I link at runtime (via Loadlibrary()) this works fine. I obtain
processadress of an exportet function wich then delivers me a pointer to
an
instance of some interface class. If that fails I know .net is not
available. Correct ?

But what if I wanted to use classes ( class __declspec( dllexport )
MyUnmanagedClassWichUsesNETInternally ) that are exportet in that dll. I
suppose that would require compiletime linking (if that is the correct
term
...) with a .lib and a .h ? Do you see any way to expose classes in my
mixed mode dll and use them in my unmanaged exe AND still be able to run
that exe even if there is no .NET Framework available.
The exe would just need to check if it is availbale and only then "use"
that
dll. This would somehow require that the CLR only gets initialized when
the
dll is "touched".

I hope this make at least a little bit sense .....

Delay loading is your friend.

See the linker option /deleayload in the help.

-cd
 
B

bonk

Thank you, this is good news. Two more little questions:

"The Visual C++ linker now supports the delayed loading of DLLs."
With what version was this feature introduced ?

Takeign the scenario I described what approach would you go for? Runtime
linking with LoadLibrary or delayloading dlls? What re the pros and
cons (pitfalls I might not yet be aware of) of these two approaches?
 
C

Carl Daniel [VC++ MVP]

bonk said:
Thank you, this is good news. Two more little questions:

"The Visual C++ linker now supports the delayed loading of DLLs."
With what version was this feature introduced ?

Quite some time ago - at least VC6.
Takeign the scenario I described what approach would you go for?
Runtime linking with LoadLibrary or delayloading dlls? What re the
pros and cons (pitfalls I might not yet be aware of) of these two
approaches?

Delay loading is seamless, and under the covers relies on LoadLibrary. When
you delay load a library, the linker generates a stub for each imported
function that loads the library and then fixes up the import table of all
functions imported from that library so you only incur the stob cost on the
firsts call to something imported from that library. It's the way to go if
you need a rich, wide API (i.e. C++ classes) across the DLL boundary.

Using LoadLibrary/GetProcAddress has the advantange of letting you choose
the DLL name at runtime, so it's a naturual for implementing plug-ins and
other systems where the optional component might be written by someone else
or at a different time from the main application. It doesn't sound like
that's your situation, so I'd go with delay loading.

-cd
 
B

bonk

Carl said:
Quite some time ago - at least VC6.




Delay loading is seamless, and under the covers relies on LoadLibrary. When
you delay load a library, the linker generates a stub for each imported
function that loads the library and then fixes up the import table of all
functions imported from that library so you only incur the stob cost on the
firsts call to something imported from that library. It's the way to go if
you need a rich, wide API (i.e. C++ classes) across the DLL boundary.

Using LoadLibrary/GetProcAddress has the advantange of letting you choose
the DLL name at runtime, so it's a naturual for implementing plug-ins and
other systems where the optional component might be written by someone else
or at a different time from the main application. It doesn't sound like
that's your situation, so I'd go with delay loading.

-cd
When you delay load a library, the linker generates a stub for each
imported function

What about whole classes rather than functions? I managed to use whole
classes that where exported from a delayloaded dll. If in that case the
linker still does that with LoadLibrary under the hood how does it
manage to expose a whole class. What happens internally when I call the
constructor of a class imported from a delayloaded dll? Do I actually
instanciate some sort of stub class/interface first wich then calls into
the dll?
 
C

Carl Daniel [VC++ MVP]

bonk said:
What about whole classes rather than functions? I managed to use whole
classes that where exported from a delayloaded dll. If in that case
the linker still does that with LoadLibrary under the hood how does it
manage to expose a whole class. What happens internally when I call
the constructor of a class imported from a delayloaded dll? Do I
actually instanciate some sort of stub class/interface first wich
then calls into the dll?

There's really no such thing as an exported class. Rather, there can be
classes for which all of the member functions (inclduing constructor and
destructor) are exported.

How does the linker do it? Very simply. Rather than putting a dependency
in your .EXE for the delay loaded DLL, and fixups in the Import Address
Table (IAT) for the imported functions, the linker fills the IAT with
pointers to a loader-stub that, when executed, reads meta-data in the EXE to
find which library to load, loads it, then patches up all of the IAT entries
to reference the functions (class members) actually exported by the DLL.

When you instantiate an "exported class", your constructor call goes to a
stub which loads the DLL, fixes up the IAT and then jumps to the actual
constructor. Subsequent calls to the constructor go directly to the
original constructor since the IAT has been updated to refer directly to the
imported functions and no longer references the stub.

-cd
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top