?
Solved

DLL as a resource ?

Posted on 1998-04-30
15
Medium Priority
?
436 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 6
  • 3
  • 2
  • +4
15 Comments
 

Author Comment

by:robg041798
ID: 1304867
Edited text of question
0
 
LVL 1

Expert Comment

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

Author Comment

by:robg041798
ID: 1304869
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
Will your db performance match your db growth?

In Percona’s white paper “Performance at Scale: Keeping Your Database on Its Toes,” we take a high-level approach to what you need to think about when planning for database scalability.

 
LVL 1

Expert Comment

by:chacko
ID: 1304870
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
ID: 1304871
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
ID: 1304872
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
ID: 1304873
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
 

Expert Comment

by:dutong
ID: 1304874
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
ID: 1304875
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
ID: 1304876
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
ID: 1304877
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
ID: 1304878
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
ID: 1304879
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 360 total points
ID: 1304880
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
ID: 1304881
So no DLL as a custom resource?  Oh well, thanks.
0

Featured Post

Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Here is how to use MFC's automatic Radio Button handling in your dialog boxes and forms.  Beginner programmers usually start with a OnClick handler for each radio button and that's just not the right way to go.  MFC has a very cool system for handli…
Introduction: The undo support, implementing a stack. Continuing from the eigth article about sudoku.   We need a mechanism to keep track of the digits entered so as to implement an undo mechanism.  This should be a ‘Last In First Out’ collec…
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.
Michael from AdRem Software explains how to view the most utilized and worst performing nodes in your network, by accessing the Top Charts view in NetCrunch network monitor (https://www.adremsoft.com/). Top Charts is a view in which you can set seve…

765 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