Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

extern "C" is not disabling name mangling

Tags:

c++

c

linker

I am trying to use a C++ library in a C framework by implement a wrapper. I've seend that you need to declare functions as extern "C" in the header file. However, when I try to link my dynamic library, name mangling is not disabled, which results in undefined symbols when I try to use my wrapper.

Here is the current header of my wrapper, SbeOtfDecoder.h :

#ifndef ITF_SBEOTFDECODER_H_
#define ITF_SBEOTFDECODER_H_                                                            


// WARNING! In a C++ wrapper for C, any exception thrown by C++ code HAS TO BE CATCHED!
// Otherwise, it is "undefined behavior".

#ifdef __cplusplus                                                                      
extern "C" {
#endif                                                                                  
///Create a new SbeOtfDecoder class instance, casted as void * for C code.
void *SbeOtfDecoder_new_with_file(char *filename);

///Destroy SbeOtfDecoder class instance.
void SbeOtfDecoder_free(void *self);
#ifdef __cpluscplus
} //extern "C"
#endif

#endif /* ITF_SBEOTFDECODER_H_ */

And corresponding functions in SbeOtfDecoder.cpp:

class SbeOtfDecoder
{
public:
    SbeOtfDecoder(char *filename);
    ~SbeOtfDecoder();
};

SbeOtfDecoder::SbeOtfDecoder(char *filename)
{
}

SbeOtfDecoder::~SbeOtfDecoder()
{
}

void *SbeOtfDecoder_new_with_file(char *filename)
{
    return new SbeOtfDecoder(filename);
}

void SbeOtfDecoder_free(void *self)
{
    delete static_cast<SbeOtfDecoder*>(self);
}

Then, linkage occurs (in a schroot) :

g++ -shared ../tmpfs/v7-flux/env/squeeze-32/DEBUG/./libs/itf_sbedecoder/src/Ir.oo ../tmpfs/v7-flux/env/squeeze-32/DEBUG/./libs/itf_sbedecoder/src/Listener.oo ../tmpfs/v7-flux/env/squeeze-32/DEBUG/./libs/itf_sbedecoder/src/SbeOtfDecoder.oo -L../tmpfs/lib   -lstdc++ -o ../tmpfs/lib/libitfsbedecoder.so

However, symbols are still mangled in the output library:

nm ../tmpfs/lib/libitfsbedecoder.so | grep SbeOtf
0001f460 t _GLOBAL__I_SbeOtfDecoder.cpp
0001f3d8 T _Z18SbeOtfDecoder_freePv
0001f37f T _Z27SbeOtfDecoder_new_with_filePc
0001f36e T _ZN13SbeOtfDecoderC1EPc
0001f368 T _ZN13SbeOtfDecoderC2EPc
0001f37a T _ZN13SbeOtfDecoderD1Ev
0001f374 T _ZN13SbeOtfDecoderD2Ev

Those symbols cannot be used by the rest of the C framework, I currently crash on unit test with this error :

~/workspace/v7-flux/build/cunit-32: symbol lookup error: ../tmpfs/v7-flux/env/squeeze-32/DEBUG/cunit/./libs/itf_sbedecoder/cunit//libtest_SbeOtfDecoder_test.so: undefined symbol: SbeOtfDecoder_new_with_file

I have no idea what I am doing wrong. If you need more insight about some stages of compilation, feel free to ask. I did not put more, since pretty much all compilation process is "hidden" in this framework.

like image 640
DainDwarf Avatar asked Mar 17 '23 09:03

DainDwarf


1 Answers

The implementation must see the extern "C" declaration in order to suppress mangling, so you need to include the interface header in the .cpp file.

like image 199
Sebastian Redl Avatar answered Mar 23 '23 19:03

Sebastian Redl