4
votes

I have to use an ugly C-library inside my c++ application. In the following explanation I will call it UglyLib. I successfully compiled UglyLib as a statically linked library. In the file ugly.h UglyLib uses an extern variable:

file ugly.h:

extern SomeStruct_type somestruct;

the variable is defined (and also used) in another file. I will call it anotherugly.c.

file anotherugly.c:

SomeStruct_type somestruct;

My c++ application is based on a generic template library (TemplateLib) and the application itself is composed by the main window GUI code and on an application library statically linked with the main window code. I will call this statically linked library ApplicationLib.

TemplateLib contains a templatelibfile.h, that exports a function foo using somestruct, the extern variable exposed by UglyLib.

file templatelibfile.h:

#include<ugly.h>
...
void foo()
{
...
do something with somestruct
...
}

foo function is used by appllibfile.h contained in the statically linked ApplicationLib.

file appllibfile.h:

#include<templatelibfile.h>
...
void applfoo()
{
...
foo();
...
}

Main Window application includes appllibfile.h

file main.cpp:

#include<appllibfile.h>
...
int main()
{
...
applfoo();
...
return 0;
}

In VS2008 when I try to compile the main window application, the microsoft linker give me this error

error LNK2001: unresolved external symbol "struct SomeStruct_type somestruct" (?somestruct@@3USomeStruct_type@@A)

If I add in templatefile.h a new definition of the extern variable the compiler stops to complain.

file templatelibfile.h:

#include<ugly.h>
SomeStruct_type somestruct
...
void foo()
{
...
do something with somestruct;
...
}

BUT I would wish to avoid it because I don't know if it is the correct thing to do (I don't want to risk to alter the semantic of UglyLib redefining a different instance of somestruct variable). Have you some suggestions in order to avoid the linking problem without redefining the somestruct extern variable? Thanks a lot!

1

1 Answers

4
votes

It's probably because of the name-mangling that the C++ compiler does. Since anotherugly.c is a C source (presumably compiled with a C compiler), the symbol somestruct will be exposed without being mangled. When you compile the rest of the files with a C++ compiler, the linker then looks for a mangled name which does not exist.

I think surrounding the declaration in ugly.h in extern "C" might solve the problem.