extern "C" 没有禁用名称修改
extern "C" is not disabling name mangling
我正在尝试通过实现包装器在 C 框架中使用 C++ 库。我发现您需要在 header 文件中将函数声明为 extern "C" 。但是,当我尝试 link 我的动态库时,名称修改没有被禁用,这导致当我尝试使用我的包装器时出现未定义的符号。
这是我包装器的当前 header,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_ */
以及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);
}
然后,linkage 发生(在 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
然而,符号在输出库中仍然被破坏:
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
C 框架的其余部分无法使用这些符号,我目前在单元测试中崩溃并出现此错误:
~/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
我不知道我做错了什么。如果您需要对编译的某些阶段有更多了解,请随时询问。我没有放更多,因为在这个框架中几乎所有的编译过程都是"hidden"。
实现必须看到 extern "C"
声明以抑制混淆,因此您需要在 .cpp 文件中包含接口 header。
我正在尝试通过实现包装器在 C 框架中使用 C++ 库。我发现您需要在 header 文件中将函数声明为 extern "C" 。但是,当我尝试 link 我的动态库时,名称修改没有被禁用,这导致当我尝试使用我的包装器时出现未定义的符号。
这是我包装器的当前 header,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_ */
以及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);
}
然后,linkage 发生(在 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
然而,符号在输出库中仍然被破坏:
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
C 框架的其余部分无法使用这些符号,我目前在单元测试中崩溃并出现此错误:
~/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
我不知道我做错了什么。如果您需要对编译的某些阶段有更多了解,请随时询问。我没有放更多,因为在这个框架中几乎所有的编译过程都是"hidden"。
实现必须看到 extern "C"
声明以抑制混淆,因此您需要在 .cpp 文件中包含接口 header。