NewsArchive
08-22-1996, 11:00 PM
Has anyone used Visual C++ with MFC to create a dll that works? If so, what
are the details of the project? Was MFC linked statically?
--
--------------------------------------------
Paul Jensen
Software Engineer / Webmaster
TTG Systems Inc.
Edmonton, Alberta
Canada
403-462-6365
pjensen@ttg-inc.com
www.ttg-inc.com
NewsArchive
09-04-1996, 11:00 PM
Paul Jensen (pjensen@ttg-inc.com) wrote:
>
> Has anyone used Visual C++ with MFC to create a dll that works?
> If so, what are the details of the project? Was MFC linked
> statically?
I have successfully used DLLs with InstallShield Express. Details:
1. I am not affiliated with InstallShield. I work for North Coast
Logic, a telecommunications company in Canton, Ohio (but they take no
responsibility for this post, which is my own).
2. I used InstallShield Express 1.1.
3. The DLL was created in MS Visual C++ 4.2, using MFC (Microsoft
Foundation Classes).
4. It did take some sweat on my part, things weren't always as
intuitive as I would have liked, but I will share my experience here.
---------------
HURDLE #1: EXPORTED NAME OF FUNCTION
What is not obvious from the Knowledge Base and documentation is the
name mangling which occurs to C and C++ functions, which is reflected in
the exported DLL name. I have to make sure my code was following C
conventions, not C++, as follows:
extern "C"
{
__declspec( dllexport ) CHAR WINAPI
NullBoxProc( HWND h, LPSTR l0, LPSTR l1, LPSTR l2, LPSTR l3 )
{
return( NullBox( h, l0, l1, l2, l3 ) );
}
}
I also have a NullBox function, not shown, which displays a dialog. I
link statically to MFC, creating ExtSetup.dll. Using the command line
"dumpbin /exports ExtSetup.dll", I see that my exported name is
"_NullBoxProc@20".
So I use the following values in ISX:
DLL Filename:
<SUPPORTDIR>\ExtSetup.dll
DLL Function name:
_NullBoxProc@20
---------------
HURDLE #2: DLLs DEPENDENT ON OTHER DLLs
Since a DLL is really a specialized EXE file, it can require DLLs to be
present. Therefore, a DLL which works in one directory may not work
once it has been moved somewhere else, such as <SUPPORTDIR>.
(Sidenote: InstallShield Express seems to make a temporary copy of my
DLL in the \TEMP (not <SUPPORTDIR>) directory before invoking it. This
caused problems for me because I was trying to keep it in the same
directory as my other DLLs. My solution is to have InstallShield call a
trivial DLL, which in turn calls the real DLL in whatever directory I
choose. Any comments from the ISX Support team on this "feature"?)
This can be hard to debug, since InstallShield just disappears without
so much as a exclamation dialog when a DLL fails. See Hurdle #3 for my
solution.
---------------
HURDLE #3: SEEING YOUR DLL THE WAY ISX SEES IT
Try invoking your DLL using this ISX-emulator. It really helps
debugging. My best guess as to what ISX is doing (to my DLL, anyway):
void IsxEmulate()
{
int err = 0;
HINSTANCE dllHandle;
FARPROC dllFunction;
CHAR rtn = 1;
if( !err )
{
dllHandle = LoadLibrary( "ExtSetup.dll" );
if( dllHandle == NULL )
{
AfxMessageBox( "Error: LoadLibrary failure" );
err = 1;
}
}
if( !err )
{
dllFunction = GetProcAddress( dllHandle, "_NullBoxProc@20" );
if( dllFunction == NULL )
{
AfxMessageBox( "Error: GetProcAddress failure" );
err = 1;
}
}
if( !err )
{
CHAR (__stdcall *func)( HWND, LPSTR, LPSTR, LPSTR, LPSTR )
= (CHAR (__stdcall *)( HWND, LPSTR, LPSTR, LPSTR, LPSTR ))
dllFunction;
rtn = (*func)( m_hWnd, "E:\\Main", "D:\\Temp\\",
"D:\\MyProg", NULL );
}
}
Make the appropriate changes to call your DLL and directories, and add a
WinMain() function, etc.
---------------
HURDLE #3: GIVING UP ON DLLs WHEN APPROPRIATE
Let's face it, DLLs can be confusing. EXE files give better diagnostics
when they fail. Also, 32-bit EXEs can call 16-bit EXEs and vice-versa.
So I simplify my DLL to the point where all it does is call an EXE (or
series of EXEs), and check the exit value.
(Sidenote: I would like to see InstallShield add a feature to their ISX
product, where it checks the exit value of EXEs and quits if nonzero.
It would sure reduce the need for DLLs during setup!)
I use the following WIN API calls: CreateProcess, WaitForSingleObject,
GetExitCodeProcess.
---------------
I hope this helps! Write me at nupp@imperium.net with comments, and
make sure to post to this news group. (And please no flames for the
long post. It is justified by the number of aggravated posts for help
recently.)
Bob Nupp (nupp@imperium.net)
NewsArchive
09-17-1996, 11:00 PM
Thanks a bundle, Bob! What did it for me was the exported name produced by
VC++ 4.1. I'm using straight C (so no C++ name mangleing) but the
Microsoft linker exports the function as:
_functionname@20
When I told ISX to call this funky name, it worked fine! What I find
really strange, is I've never seen this before in Windows programming.
I've always used the straight function name and the loader has been able to
resolve it.
Any comments InstallShield guys?
Thanks again, Bob.
Kevin
NewsArchive
09-18-1996, 11:00 PM
Kevin W. Hammond <hammondk@ctt.com> wrote in article
<01bba5a0$67b4e780$0ffab6c6@callisto>...
> Thanks a bundle, Bob! What did it for me was the exported name produced
by
> VC++ 4.1. I'm using straight C (so no C++ name mangleing) but the
> Microsoft linker exports the function as:
>
> _functionname@20
>
> Any comments InstallShield guys?
>
As you have discovered, the Microsoft compiler "mangles" function names for
'C' modules under certain conditions. You are almost surely using the
_declspec(dllexport) syntax in your function declaration without listing
the function name in your .DEF file. Under these conditions the MS compiler
will "mangle" the name in the fashion mentioned. If you add the function
name to the exports section of your .DEF file then the function will be
exported as "functionname" and not "_functionname@20". This will allow you
to specify the more "user friendly" name within ISX. ISX just uses the
LoadLibrary()/GetProcAddress() Windows APIs to call ISX extension dlls, so
it needs the exact name.
David
InstallShield Corporation
vBulletin® v3.6.4, Copyright ©2000-2010, Jelsoft Enterprises Ltd.