How to remove surrounding characters around a symbol in a shared library?

763 views Asked by At

I compiled a library with g++ and I want to link against it with gcc.
Problem is I get an error while linking against it:

undefined reference to 'functionName`

(functionName is the function name in the library)

although the function exists in the symbols list and I specify the path to gcc while linking.

It happens because the function appears in the list with surrounding characters (I think this is for overriding?):

Z12functionNameiSt9__va_list

I know that to remove these characters I should surround the function declaration with extern "C". And I did that:

//header.hpp
extern "C" int functionName(int argc, ...);

But the surrounding characters still appear around the function name in the symbols list. And that's why gcc can't find it.

I'm cross compiling for linux arm yokto with arm-poky-linux-gnueabi-gcc and arm-poky-linux-gnueabi-g++ on Ubuntu desktop 16.

Why aren't the surrounding characters being removed and how can I remove them? I will never override this function so if these are really for overriding then I don't need them.


edit:

Solved. The function signature in its declaration was different from the signature in its definition... So the extern keyword was for nothing.

int functionName(int argc, ...); //declaration
int functionName(int argc, va_list args) //definition
2

There are 2 answers

1
Basile Starynkevitch On

The "surrounding characters" are actually for name mangling. So better speak of mangled names.

You probably should add

#ifdef __cplusplus
extern "C" {
#endif

near the start of your (public) header file (that you'll better code in the common subset of C and C++), and the matching

#ifdef __cplusplus
}; // end of extern "C"
#endif

near its end. See also this.

You should wrap all your public header (and perhaps standard C headers included by it) with such things (not only individual functions).

You could compile with gcc -H to list the included headers or g++ -C -E to get the preprocessed form (and examine it).

4
Olivier On

Those characters are name mangling. They encode the function signature so C++ overloading can work correctly (eg. int foo(int) and int foo(float) are different symbols).

If your API is C, you need to fix the library to not have the mangling. Build it as C or add extern "C" in its code. If your API is meant to be C++, remove the extern "C" from your header.

If the mangled names don't match (different mangling), then you probably have an ABI compatibility problem. In that case, trying to fix the link problem is the wrong solution. You need to make sure you build your code with the same ABI as the library instead.

The c++filt tool should be able to decode the mangled symbol into a signature. That can be useful to figure out what the difference is about.

Given you built the library with g++ and are trying to link with gcc, it's likely you want a C API and rebuilding the library with the extern "C" in place is what you need.