views:

166

answers:

5

I'm in linker paradise now. I have a C library which only compiles in Visual C++ (it probably works in gcc) if:

  1. I compile it as C++ code
  2. Define __cplusplus which results in all the declarations being enclosed in extern "C" { }

So, by doing this I have a static library called, say, bsbs.lib

Now, I have a C++ project called Tester which would like to call function barbar in declared in bsbs.h. All goes fine, until I try to link to bsbs.lib where I get the all-too-familiar:

Tester.obj : error LNK2001: unresolved external symbol _foofoo

And it always seems to be foofoo which cannot be resolved regardless of which function I call in Tester (barbar or anything else).

Update: I've expanded on Point 2 as requested. Thanks a lot for the help guys!

#ifndef _BSBS_H
#define _BSBS_H

/* Prevent C++ programs from name mangling these definitions. */
#ifdef __cplusplus
extern "C" {
#endif

#include <stdio.h>
#include <setjmp.h>
.......
.......
#ifdef __cplusplus
}
#endif

#endif /* _BSBS_H */

This is the "main" header file, so to speak. All the important functions are here. But there are other header files called by the bsbs.c file which are not enclosed in extern "C" {}.

Solved: OK, this is quite weird, but I removed the extern C bit from the header file in bsbs, compiled it as a C++ project (even though all the files are .c and removed the __cplusplus define) and it worked! I got the idea after looking at the symbol list. Everything was mangled except the ones enclosed in extern C (doh) and it was asking for an unmangled symbol so I figured something was amiss.

A: 

I'm assuming you've added a linker reference. E.g.:

#pragma comment(lib, "bsbs.lib")
Jim Lamb
Well, I defined the input libraries elsewhere so it's reading `bsbs.lib`
Jacob
+2  A: 

There may be a dependency in the c library you're not including in your link. Does the c library you're including really a reference to a DLL? If so there's a program called 'depends' which will tell you what the other required DLL's are.

Jay
I don't think so since `foofoo` is defined in `bsbs.lib` and it seems to be independent.
Jacob
A: 

Perhaps the compiler/linker combination needs to be made aware of which APIs are to be exported/imported? If so I'd try adding the appropriate __declspec (e.g., dllimport and/or dllexport) to the C++ library.

fbrereto
+1  A: 

If you declare them as extern C in the lib (which is unnecessary, if you're calling them from C++), then they must be extern C in your headers.

DeadMG
But not in the headers of `Tester` which is C++, right?
Jacob
If they're extern C, they're extern C. You can't mix and match. If the lib exports them as extern C, then you MUST import them as extern C.
DeadMG
A: 

Does your lib file import any other lib files? You can compile a lib file to either explicity link lib files or implicitly. One way you get the lib files in a huge ball, the other you get them as separate libs that all need linked at compile time in the final app. If foofoo is imported in your lib file from another lib file, then include that lib file in your final project. This is my best guess from what you described, and is by far the most common thing I get asked when dealing with lib files thru co-workers..

Jay Kramer
I don't think that's the case since `foofoo` seems to be completely defined.
Jacob