473,320 Members | 2,133 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

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

DLL's, Borland & alot of Frustrations

Airslash
221 100+
Hi,

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 4677
weaknessforcats
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
Airslash
221 100+
Yes,
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();
  2.  
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
weaknessforcats
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
  1. ;BEGIN ADLL.DEF FILE
  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 
  9. EXPORTS 
  10. ;Exported Name    C++ Mangled Name
  11. AreaOfSquare   =  ?AreaOfSquare@@YGHHH@Z
  12. DisplayFromDll =  ?DisplayFromDll@@YGXXZ
  13. ;END DEF 
FILE

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;
  6.  
Dec 8 '09 #4
Airslash
221 100+
woah,

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
RRick
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
weaknessforcats
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, 176 views)
Dec 8 '09 #7
Airslash
221 100+
Alright,

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
weaknessforcats
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
Airslash
221 100+
Well,

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
weaknessforcats
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
Airslash
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

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

Similar topics

0
by: Mike Ruskai | last post by:
I've been trying to implement database axis using the C api for a many-threaded application (several, actually), and keep running into a problem on server disconnect. One of the main reasons is to...
1
by: AP | last post by:
Hi, Is there anyway to call a DLL developed in c# from a borland c++ 5.0 application? Is there anyway to do this without having to have the .NET framework installed (compile C# to native...
1
by: Furer Ramon | last post by:
I need to call the function mul3 in a dll: extern "C" unsigned __declspec(dllexport) mul3(unsigned npts, const double * src, double * dst); from vb.net how can i do this? Greets
1
by: Terry | last post by:
Is there any hope of using Borland Developer Studio 2006 to link in a DLL compiled by MS Visual C++ version 6? I have a Win32 DLL from a company named Vocera. The DLL defines C++ classes that I...
1
by: Michael Buechel | last post by:
Hi NG, I've copied this from the article Q309801 (http://support.microsoft.com/default.aspx?scid=kb%3Ben-us%3B309801). ---- schnipp --------- You may receive an LNK2019 error message when you...
3
by: deepha | last post by:
hai , I have a app which is using a xxxx.lib file. I am compiling this application on borland c++ compiler using make file. i am having the xxxx.dll also. I just want compile the...
17
by: Fabry | last post by:
Hi All, I'm new of this group and I do not know if this is the correct group for my question. I have a DLL with its export library (.lib) wrote in Borland C++ 6. In borland everything is OK and...
1
by: =?Utf-8?B?SmNr?= | last post by:
I am trying to access the registry from a normal user by the following code .... but failed!! However, it works under admin user logon. I think I need to grant some access right to the normal...
7
by: SteelNetNob | last post by:
I have created a COM callable DLL in C# .NET 2.0 and created a TLB from the assembly using the .NET regasm tool. In Borland C++ Builder 4.0 I go to Project->Import Type Library-> and find my...
0
by: DolphinDB | last post by:
The formulas of 101 quantitative trading alphas used by WorldQuant were presented in the paper 101 Formulaic Alphas. However, some formulas are complex, leading to challenges in calculation. Take...
0
by: DolphinDB | last post by:
Tired of spending countless mintues downsampling your data? Look no further! In this article, you’ll learn how to efficiently downsample 6.48 billion high-frequency records to 61 million...
0
by: ryjfgjl | last post by:
ExcelToDatabase: batch import excel into database automatically...
0
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
1
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
0
by: jfyes | last post by:
As a hardware engineer, after seeing that CEIWEI recently released a new tool for Modbus RTU Over TCP/UDP filtering and monitoring, I actively went to its official website to take a look. It turned...
0
by: ArrayDB | last post by:
The error message I've encountered is; ERROR:root:Error generating model response: exception: access violation writing 0x0000000000005140, which seems to be indicative of an access violation...
0
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
1
by: Shællîpôpï 09 | last post by:
If u are using a keypad phone, how do u turn on JavaScript, to access features like WhatsApp, Facebook, Instagram....

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.