472,145 Members | 1,486 Online
Bytes | Software Development & Data Engineering Community
Post +

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 472,145 software developers and data experts.

DLL's, Borland & alot of Frustrations

221 100+

I'm sorry if this is not the correct forum, but since I'm programming in C++ this looked like the best place.

I'm trying to make a nice DLL file for the company where we place all functions, classes and definitions in it to share amongst our various software projects.
These things are written in C++.

At the moment I havent done anything special yet to the files suchas including those magic __ words for the export etc.

We are using CodeGears Borland C++ builder as main development IDE.
Our first test was to put our GDI+ wrapper in the DLL and call it from one of our projects.

But we have some issues getting the DLL linked.
Can anyone provide me with a explanation as to what needs to be done in order to make the C++ classes inside the DLL exportable and to link the DLL to our projects using Borland CodeGears?

this IDE is driving me nuts.....in VS its just a few clicks to get it sorted....
Dec 8 '09 #1
11 4513
9,208 Expert Mod 8TB
You are using Windows, yes?

First decide on where you are going to use explicit or implicit linking.

Explicit linking means you will call LoadLibrary to loas the DLL and then call GetProcAddress for the address of your function in the DLL and then you will call the function at that address.

Implicit linking means you will call the DLL function as you would any other function. Here you use the .h file created by the DLL build. The function you call in that .h does the LoadLibrary, the GetProcAddress and the call to the function at that address. This implicit linking requires a _dllimport in the .h file function prototype. If this is not there, then you have to use explicit linking.

Maybe you could explain further about your linking issue.
Dec 8 '09 #2
221 100+
We're developing for Windows Server 2003 at the moment.

The basic idea is to have one DLL where all the classes, structs and functions are that are commonly shared between the various small applications that we develop.
An example I recently developed would be a GDI+ wrapper.

At the moment I have created the header and class file for this wrapped and placed them inside the DLL project. Nothing else in it at the moment.

The idea now is that when I create a new application, I can simply type for example:

Expand|Select|Wrap|Line Numbers
  1. Wrapper x = new Namespace::Wrapper();
Without having to worry about all the required files for this class, since they're all in the DLL and beeing linked for the Project.
What I would like to know, do I need to add anything speciall to the class definitions inside the DLL or in the Project.

We've been trying several things with the #define and #pragma statements in a project, and the project compiled, but as soon as we called one of the classes/functions from the DLL the application refused to run or even start up at some point.
Dec 8 '09 #3
9,208 Expert Mod 8TB
First, all the code in the DLL can be in C++ except the functions you call from your program.

A DLL is an old C whiz-bang where you use the name of the DLL funcrtion in your program:

Expand|Select|Wrap|Line Numbers
  1. FARPROC ptr = GetProcAddress(hModule, "AreaOfSquare");
Unfortunately, AreaOfSquare is never found in the DLL. The C++ compiler has mangled the name in the DLL. Therfore, the function in the DLL must be extern "C":

Expand|Select|Wrap|Line Numbers
  1. //In the DLL:
  2. extern "C"
  3. int __stdcall AreaOfSquare(int len, int wid)
  4. {
  5.      ACplusplusFunction();
  6. }
The ACplusplus function does not need to be extern "C" since it is never called using a literal "ACplusplus".

So, your DLL interface must be designed correctly.

The extern "C" can be avoided by using a DEF file to export the mangled name as an alias:

Expand|Select|Wrap|Line Numbers
  2. ;This DEF file is required becuase the argument to GetProcAddress()
  3. ;for the function is a C-string and it will never be equal to the
  4. ;C++ mangled name for the function
  5. ;This DEF file maps the mangled name to a name that can be used with GetProcAddress()
  6. ;Note also: Change project settings in Visual Studio to send the LINK this def file.
  7. ;Visual Studio.NET: Project Properties/Linker/Input/Module Definition File/...Path to the def file\Adll.def
  8. LIBRARY ADll 
  10. ;Exported Name    C++ Mangled Name
  11. AreaOfSquare   =  ?AreaOfSquare@@YGHHH@Z
  12. DisplayFromDll =  ?DisplayFromDll@@YGXXZ
  13. ;END DEF 

Lastly, the DLL export functions must use the __stdcall convention (WINAPI).

If you use GetProcAddress and you are successful in getting a non-null FARPROC returned, I would typecast that pointer into a function pointer of the correct type. That way when I call the DLL function inside my program, I can just use the name that was coded inthe DLL in the first place:

Expand|Select|Wrap|Line Numbers
  1. FARPROC ptr = GetProcAddress(hModule, "AreaOfSquare");
  2. int (__stdcall *AreaOfSquare)(int, int);
  3.     //Type-cast the address returned from GetProcAddress to the function pointer type
  4.     AreaOfSquare = reinterpret_cast<int (__stdcall*)(int,int)>  (addr);
  5. cout << "The area of a 6x8 square is " << AreaOfSquare(6,8) << endl;
Dec 8 '09 #4
221 100+

complex :)

But if I understand it correctly, I need to make some kind of C function that for example fetches my C++ class for me, and that should work without a problem then ?
Dec 8 '09 #5
463 Expert 256MB
I have worked a little bit with DLLs and found that they have issues with what can cross between the DLL library to your application.

For example, if something is newed in the DLL, then it needs to be deleted in the DLL. STL containers in the DLL have issues when accessed/modified by your app.

I'm not sure of the specifics and this was a while ago. Perhaps someone else can clarify these issues.
Dec 8 '09 #6
9,208 Expert Mod 8TB
It's not that complex.

I would get a copy of Windows via C/C++ by Jeffrey Richter where all this is documented.

But yes, you write a function in the DLL that is called by the program. That function can create C++ objects, call member functions, etc. But the name of this function cannot be mangled. That's because you are asking for the funciton by name (a literal) in the GetProcAddress call. If the compiler has mangled the name in the DLL, then the mangled name will never match the literal in the GetProcAddress call. Therefore the function must be extern"C" in the DLL code.

Please note: Bacause the DLL is compiled in C++ and the interfacing functions are called like C functions, you are quite OK to use this C++ DLL in a hard C program. Heck if that C program interfaces FORTRAN, you can access C++ code from FORTRAN programs.

I have attached a ZIP for a DLL example that works in Visual Studio.NET 2008. Compile using a DLL project.
Attached Files
File Type: zip DLL.zip (1.6 KB, 174 views)
Dec 8 '09 #7
221 100+

I'll definitly give it a look when I'm back at work (23.00 while writing this).
Been looking around a bit more on the Internet regarding the whole stuff of DLLs and doubting a bit whether or not I should make a static .lib instead of the dynamic .dll file.

Most things are still a big mystery to me on this subject since I'm only a junior C++ not so long graduated, but have to bite the bullet sometime.

Definitly big thanks for the replies.
Still got a load of questions and probably will run into more problems, but at least I have a better understanding of the whole subject.
Dec 8 '09 #8
9,208 Expert Mod 8TB
A static lib will make your program larger and removes the ability to change the program by just chaing the DLL. Often it's easier to keep the main installed base and just produce new DLL versions for your upgrades.

Also, your program could read a .ini file and in there could be the name of the DLL to use. This allows your program to chnage the name of the DLL that's loaded without changing the code.

Try, always, to have no hard-coded assumptions in that main program.

A Visual Studio. NET DLL project produces both a .dll and .lib. The difference is that if your use the .lib, the function there calls LoadLibrary, GetProcAddress and the function in the DLL. This is the implicit linking. You will notice a __dllimport in the .h file.
Dec 9 '09 #9
221 100+

we solved the problem finnally.
Call me a nunchkimpoop but the problem was that the application couldn't find the DLL and the Borland Debugger wasn't smart enough to tell us so.

We found out by running the compiled exe files outside the IDE and then got the missing DLL error.
Now everything is working as it should and the DLL is working like a charm.

Even have classes in it without C function calls, just plain C++ stuff that can be called without problems. Was a bit tricky to get the __dllexport and __dllimport stuff in the right places, but all works.

a new thing learned :)
Dec 9 '09 #10
9,208 Expert Mod 8TB
That's great.

This is an example of no knowledge gained unless you first experience the necessary tears.

The necessary tears occur at 1:30am after a week of 16 hour days and you finally explode and throw your keyboard through your monitor, tears streaming down your face, shouting "Why doesn't this %%*($%^ thing compile!!!".

At this point you reach a teachable moment.

No one escapes.
Dec 9 '09 #11
221 100+
it's also why I like the language so much. Or programming in General.

When you think you've found the solution, some ugly bug appears or something else goes wrong.
There's always a challenge.
Dec 9 '09 #12

Post your reply

Sign in to post your reply or Sign up for a free account.

Similar topics

reply views Thread by Mike Ruskai | last post: by
1 post views Thread by AP | last post: by
1 post views Thread by =?Utf-8?B?SmNr?= | last post: by
reply views Thread by leo001 | last post: by

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.