tags:

views:

3257

answers:

6

Hi!

I'm trying to use a dll, namely libcurl, with my program, but, it's not linking. Libcurl comes with .h files that I can include (takes care of dllimport), but then I quess I must specify wich dll to actually use when linking somehow... How do I do that? I'm compiling with borland c++ builder, but I really whant to know how theese things work in general...

EDIT: This is the code (straight c/p from curl homepage)

bool FTPGetFile::ConnectToFTP(string ftpServer){
CURL *curl;
CURLcode res;
curl = curl_easy_init();
if(curl) {
 curl_easy_setopt(curl, CURLOPT_URL, "curl.haxx.se");
 res = curl_easy_perform(curl);
 return true;
}else{
 return false;
}
}

And here are the errors:

[Linker Error] Error: Unresolved external '_curl_easy_init' referenced from C:\PROJECTS\PC\TOOLBOX\DEBUG_BUILD\FTPGETFILE.OBJ
[Linker Error] Error: Unresolved external '_curl_easy_setopt' referenced from C:\PROJECTS\PC\TOOLBOX\DEBUG_BUILD\FTPGETFILE.OBJ
[Linker Error] Error: Unresolved external '_curl_easy_perform' referenced from C:\PROJECTS\PC\TOOLBOX\DEBUG_BUILD\FTPGETFILE.OBJ

EDIT 2: As per suggestion from joe_muc I have made the lib files with the implib tool and included them in the linker path. I still get the same errors.

+1  A: 

Normally, if you are linking against a Windows DLL, you'll need to pass the name of either the DLL or the import library to the linker otherwise it won't be able to link the executable.

The error message you quote suggests that you will indeed need to specify either the DLL or the import library. When you built curl as a DLL, it probably created both a .lib and a .dll file. Point your linker at the .lib file and when you start up your application, make sure that the .dll file is in a directory that is in the path so the loader can find it.

Timo Geusch
Added the code and the errors to the question
c0m4
I dont have a .lib file as I downloaded libcurl precompiled... I have added the path to the dlls to the linker. Still no luck.
c0m4
I would try to build the library yourself then. It might be that the library you are using is targeted at Visual C++ uses as the Microsoft Linker doesn't necessarily need an import library.
Timo Geusch
+1  A: 

By far the most common solution is to use the import library (.lib) which you should get as part of building libcurl. This tells the (static) linker how to prepare the EXE for the dynamic loading.

MSalters
Is .lib the same as .a? All I have is .a files, .dll files and the .h files.
c0m4
A: 

Have you tried adding the .h file to your project?

Maltrap
Yes, the h file is there
c0m4
+2  A: 

There should be a program called IMPLIB.EXE in the bin or app directory for builder. Run that against the dll to create a .lib file.

edit: Online Docs

jmucchiello
The new link is [IMPLIB.EXE, the Import Library Tool](http://docwiki.embarcadero.com/RADStudio/en/IMPLIB.EXE,_the_Import_Library_Tool)
yanjost
+2  A: 

As mentioned, you will need the static .lib file that goes with the .dll which you run through implib and add the result lib file to your project.

If you have done that then:

  • You may need to use the stdcall calling convention. You didn't mention which version of Builder you are using, but it is usually under Project options - Advanced compiler - Calling convention.
  • You may need to enable MFC compatibility option.
  • It could be a name mangling issue (Project options - C++ compatiblity options).
  • Or generation underscores
  • Or advanced linker options "Case_insensitive-link" on or off

libcurl appears to be C code; but if it is C++, note that Microsoft and Borland classes are generally not compatible. There are supposed to be tricks to get them to work, but it is a real mess to deal with and I have never had success. C coded DLLs should work.

Roger Nelson
Great answer, thanks! I'll try this stuff.
c0m4
The "generation underscore" thing seemed promising as my original errors went away. However, it produced TONS of other errors with stuff that worked before. I guess it was not ment to be for me... Still marking this answer as correct as it was very helpful. Oh, and can I just say: Borland sux.
c0m4
I am disappointed you don't like the Borland compiler I have been using Borland C++ for years and have always preferred Borland C++ to every Microsoft C++ of the same vintage (Visual Studio 2002 for example was horrible). I do wish though that calling conventions were the same.
Roger Nelson
+1  A: 

Use "Depends.Exe" to browse the .DLL, and find the exact names of the functions that you want to use, then add the .lib file for the dll (or create it using borland's implib), and include the .lib file in your bpr project file, by right-clicking and adding it to the project. then at the top of your code, use __declspec(dllimport) to please the linker gods.

Joshua