问题
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.
回答1:
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.
来源:https://stackoverflow.com/questions/27900240/extern-c-is-not-disabling-name-mangling