DLL as a resource ?

A Watcom C++ program I have written uses LoadLibrary() to access a precompiled DLL.  The DLL is in a separate file, but I would like to merge it into the .exe file.  It'd be nice if I could make the DLL a resource in my .exe file and then load it at run-time (works for bitmaps)...
Is it possible and how can I do it ?      
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

robg041798Author Commented:
Edited text of question
I could not get the intension behind this. You can do a static link to solve the problem
robg041798Author Commented:
I've tried static linking before, but Watcom's docs are
sketchy on this.  I've declared the DLL functions as below:

extern "C" {
   void __declspec(dllexport) _stdcall somefunctionindll(void);

In place of __declspec(dllexport) _stdcall I've also tried:

1) _export _stdcall
2) _stdcall

...Linking gets me:

 _somefunctionindll@8 is an undefined reference, etc.

I'm missing something.

Cloud Class® Course: Microsoft Office 2010

This course will introduce you to the interfaces and features of Microsoft Office 2010 Word, Excel, PowerPoint, Outlook, and Access. You will learn about the features that are shared between all products in the Office suite, as well as the new features that are product specific.

Your problem seems to be name mangling. Microsoft has it's own name mangling which is not compatible with Watcom. Could you create a new project in MSVC++ Appwizard and try to port all code from Watcom to Microsoft and compile and see? I hope this may solve the problem.
robg041798Author Commented:
I don't have MSVC++ to try a port.  I'm surprised that Watcom
cannot do this.
  Shouldn't extern "C" turn off name mangling to avoid the
problem?  Might there be a Watcom flag to obtain MSVC++ compatible mangling ?

extern "C" doesn't turn off name mangling for MSVC, you need to specify __cdecl, as in:

extern "C" int __cdecl myfunc()

you could try

__declspec(dllexport) int __cdecl MyFunc()

Hope this helps
I think extern "C" does turn off name mangling, but it doesn't export the function from DLL, and it doesn't specify calling convention.

Your problem might be that you're not linking the .lib file generated when your DLL is compiled.

You can define you own binary resource type for that DLL, and you can load it at runtime, just like the bitmap, but if you want the 'resource' to act as DLL(to load and call the function), you must make it like a file(executable) in memory, I don't know the app function detail, so can not figure out how to do next.
You can load up the DLL using LoadLibrary() to get it loaded and a HANDLE to the module.

Call the Win32 function ::FindResource() to locate a specific resource, then the Win32 function ::LoadResource() to get it.


               LPCTSTR of RESOURCE TYPE);

robg041798Author Commented:
Sorry, but I still haven't got it...

How do I create a custom resource for my DLL and link it to my .exe?
How do I then access the functions from the custom resource ?

Sample .cpp & .rc code would be great... I'm putting more points on this one!
Just build your dll as you would a normal one, but all it would contain is your resources:  bitmaps, strings, .wavs, .avis, whatever.  The dll management code would just take care of load/unload (you can probably use the skeleton code provided by your DLL wizard because you don't have to manage any sort of DLL state, or function exports).  In your application:

//  code to load library (somewhere in your app init)
//  ghMyResDll is an app-global variable
HMODULE ghMyResDll = ::LoadLibrary("pathtodll.dll");

When you need a resource, use a function similar to this:

//  global API I created to load external resource
HGLOBAL MyGetResource(LPCTSTR lpszIDName, LPCTSTR lpszType)  {
  HRSRC hRes = ::FindResource(ghMyResDll, lpszIDName, lpszType);

  return ::LoadResource(ghMyResDll, hRes);

To load your resource:
HGLOBAL hMyCursor = MyGetResource("IDC_CURSOR1", RT_CURSOR);

Of course, I've ommitted any error trapping, but that's basically all the code you'd need to load resources from an external DLL.  Notice in the function example that there's an lpszType.  This corresponds to the types of resources that can reside in a DLL/Executable.  These types can be a string for the type, or a #declared constant from Win32...these constants are, to quote from the MSDN library online:

RT_ACCELERATOR Accelerator table
RT_ANICURSOR Animated cursor
RT_ANIICON Animated icon
RT_BITMAP Bitmap resource
RT_CURSOR Hardware-dependent cursor resource
RT_DIALOG Dialog box
RT_FONT Font resource
RT_FONTDIR Font directory resource
RT_GROUP_CURSOR Hardware-independent cursor resource
RT_GROUP_ICON Hardware-independent icon resource
RT_ICON Hardware-dependent icon resource
RT_MENU Menu resource
RT_MESSAGETABLE Message-table entry
RT_RCDATA Application-defined resource (raw data)
RT_STRING String-table entry
RT_VERSION Version resource

And from ::LoadResource()'s remark section:
"...If the high-order word of the lpName or lpType parameter is zero, the low-order word specifies the integer identifier of the name or type of the given resource. Otherwise, those parameters are long pointers to null-terminated strings. If the first character of the string is a pound sign (#), the remaining characters represent a decimal number that specifies the integer identifier of the resource’s name or type. For example, the string '#258' represents the integer identifier 258..."
Er I meant ::FindResource() in the last part of the last comment!

But, perhaps I should be clearer.  You can create a resource ONLY dll and use it as I outlined above.
robg041798Author Commented:
Actually I should have been clearer.  I have a commercial DLL in a separate file that I access from my .exe using LoadLibrary.  My goal is to glom the DLL and my program together so that everything resides in one file.  I don't have the DLL source code to recompile and the company "doesn't support static linking."  But is it possible to...
1) Make the DLL a custom resource in my project (RT_RCDATA?)
2) Load the resource and get an HMODULE for the DLL it contains
3) Access functions from HMODULE using GetProcAddress...
Since the answer will likely be over my head please give sample code or be gentle in calling me insane ;-)
If the code is in a DLL, you can not make it part of your EXE unless you have the source code and add it to your application.

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
robg041798Author Commented:
So no DLL as a custom resource?  Oh well, thanks.
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
System Programming

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.