Solved

DLL as a resource ?

Posted on 1998-04-30
15
385 Views
Last Modified: 2013-11-20
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 ?      
0
Comment
Question by:robg041798
  • 6
  • 3
  • 2
  • +4
15 Comments
 

Author Comment

by:robg041798
Comment Utility
Edited text of question
0
 
LVL 1

Expert Comment

by:chacko
Comment Utility
I could not get the intension behind this. You can do a static link to solve the problem
0
 

Author Comment

by:robg041798
Comment Utility
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.


0
 
LVL 1

Expert Comment

by:chacko
Comment Utility
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.
0
 

Author Comment

by:robg041798
Comment Utility
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 ?

0
 

Expert Comment

by:mulenga
Comment Utility
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
0
 
LVL 3

Expert Comment

by:byang
Comment Utility
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.


0
How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

 

Expert Comment

by:dutong
Comment Utility
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.
0
 
LVL 2

Expert Comment

by:igroove
Comment Utility
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.

Signatures:

HRSRC ::FindResource(HANDLE to MODULE, LPCTSTR of RESOURCE NAME,
               LPCTSTR of RESOURCE TYPE);
HGLOBAL ::LoadResource(HANDLE to MODULE, HANDLE to RESOURCE);


0
 

Author Comment

by:robg041798
Comment Utility
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!
0
 
LVL 2

Expert Comment

by:igroove
Comment Utility
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..."
0
 
LVL 2

Expert Comment

by:igroove
Comment Utility
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.
0
 

Author Comment

by:robg041798
Comment Utility
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 ;-)
0
 

Accepted Solution

by:
bobplace earned 120 total points
Comment Utility
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.
0
 

Author Comment

by:robg041798
Comment Utility
So no DLL as a custom resource?  Oh well, thanks.
0

Featured Post

Highfive + Dolby Voice = No More Audio Complaints!

Poor audio quality is one of the top reasons people don’t use video conferencing. Get the crispest, clearest audio powered by Dolby Voice in every meeting. Highfive and Dolby Voice deliver the best video conferencing and audio experience for every meeting and every room.

Join & Write a Comment

Introduction: Displaying information on the statusbar.   Continuing from the third article about sudoku.   Open the project in visual studio. Status bar – let’s display the timestamp there.  We need to get the timestamp from the document s…
Introduction: Dialogs (1) modal - maintaining the database. Continuing from the ninth article about sudoku.   You might have heard of modal and modeless dialogs.  Here with this Sudoku application will we use one of each type: a modal dialog …
This video will show you how to get GIT to work in Eclipse.   It will walk you through how to install the EGit plugin in eclipse and how to checkout an existing repository.
Illustrator's Shape Builder tool will let you combine shapes visually and interactively. This video shows the Mac version, but the tool works the same way in Windows. To follow along with this video, you can draw your own shapes or download the file…

762 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

10 Experts available now in Live!

Get 1:1 Help Now