-
Linker Problems
Hi,
I'm trying to statically link my app to a third-party JPEG library. I've built the third-party library in question as a static lib and have copied the output libs to my project and added them to my linker input.
I've copied required headers into my headers directory and am attempting to use some of the types defined by the library. However, I keep getting link errors and the linker complains that it cannot resolve the external symbols that I thought would be in the lib.
I'm confused and am not sure how to proceed in resolving the issue. Can anyone offer any insight as to where I should start, or maybe point me in the right direction?
Thanks,
Kent
-
The question is: is this a C library? If so, it could be a missing extern "C" declaration that wraps the types in question. Can you post the actual linker errors? Also, show us how you're using these types in your code. A single declaration will do.
Danny Kalev
-
Thanks a lot Danny. I am using the library like this:
struct jpeg_decompress_struct cinfo;
struct jpeg_error_mgr jerr;
cinfo.err = jpeg_std_error(&jerr); //link fails on this line
jpeg_create_decompress(&cinfo); //link fails on this line
Which was producing link errors like this:
error LNK2019: unresolved external symbol "struct jpeg_error_mgr * __cdecl jpeg_std_error(struct jpeg_error_mgr *)" (?jpeg_std_error@@YAPAUjpeg_error_mgr@@PAU1@@Z) referenced in function <snip>
After reading your comment I could see that the linker was looking for the mangled C++ name. To fix it, I tried wrapping my include in the extern declaration:
extern "C" {
#include <jpeglib.h>
}
That satisfies the linker. But is that an acceptable thing to do or is it dodgey?
Ideally, shouldn't the library check whether cplusplus is defined and do the whole extern "C" thing for you?
Thanks again,
Kent
-
Its not dodgy, its totally acceptable.
Its just saying use C naming conventions, which avoids the mangled names (function_name@@junk@morejunk@etc).
No, it should not be done for you, that would introduce a lot of problems -- you are asking the IDE to make a decision for you, to 'guess' what you meant. It would be like having it substitute the closest variable name thats legal if the identifier does not exist already (fix your typos for you, think Word) -- you *could* do that, but do you really want a compiler to make this kind of decision? Try to write a program in Word and see how awful it would be...
The cplusplus define itself is dodgy, but its been around too long to change - I preferred the file extension method (.c / .h for C and .cpp / .hpp for c++) better than some odd #define hackery, but no one ever asks me.
-
 Originally Posted by jonnin
The cplusplus define itself is dodgy, but its been around too long to change - I preferred the file extension method (.c / .h for C and .cpp / .hpp for c++) better than some odd #define hackery, but no one ever asks me.
I wouldn't rely too much on file extensions for many reasons. First, they are not standard. Secondly, extern "something" declarations aren't restricted to C/C++ but to other languages so in theory (as well as in practice) you can find extern "ada" or extern "fortran" linkage declarations that refer to libraries written in these languages.
As for the OP's question: it's not dogy, as jonnin said, but the common practice is to create a header wrapper that contains
extern "C" {
#include <jpeglib.h>
}
And then #include that header instead of <jpeglib.h>.
Danny Kalev
-
Extern is fine (we still use some fortran, aerospace guys use it), I just have a problem with the #define (cplusplus) that is not visible anywhere (the compiler defines it behind you back based on C vs C++). But I hate invisible #defines of any sort .. if its not defined in a source file, it should not be able to exist. I am not going to win that one, but none of MY code is going to hide defines in the project files or makefiles or whatever you call it, unless I encounter something that simply cannot be done another way (haven't yet). There is little worse than a bunch of source that won't compile until you muddle out which defines should be on, with little or no comments beyond the name of the defines.
-
As problematic as hidden defines are, there is escape from it in a few rare cases such as this one. How for example would you implement the __FILE__ and __DATE__ macros? The ifdef C++ stuff is necessary because C header files that are also used in C++, say <cstring> or <ctime> are often mapped to two entirely different files. Here, you have no file extension that can help the compiler out, but the substantial differences between <string.h> and <cstring> require some mechanism for on-demand rewriting of these files. The differences include namespace issues, substitution of C macros with real functions in C++, overloading of certain functions (which isn't possible in C) and other subtle core language differences such as restrict pointers which exist only in C. It's a kludge, but I can't think of a better workaround.
Danny Kalev
-
There isn't a better way, but I don't have to like it =)
-
Last edited by Danny; 02-14-2005 at 09:17 AM.
Danny Kalev
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
Forum Rules
|
Top DevX Stories
Easy Web Services with SQL Server 2005 HTTP Endpoints
JavaOne 2005: Java Platform Roadmap Focuses on Ease of Development, Sun Focuses on the "Free" in F.O.S.S.
Wed Yourself to UML with the Power of Associations
Microsoft to Add AJAX Capabilities to ASP.NET
IBM's Cloudscape Versus MySQL
|
Bookmarks