C++ 共享库中的符号

C++ 共享库中的符号,c++,c,gcc,shared-libraries,C++,C,Gcc,Shared Libraries,我已经学习了如何生成共享库。我添加了一些较小的东西,因为我想测试一些东西。以下是ma源代码: strong文本 #ifndef foo_h__ #define foo_h__ void foo(void); class CFoo { public: void fooing1(); void fooing2(int a); void fooing3(int a, int b = 0); }; #endif // foo_h__ g++ -c -Wall -

我已经学习了如何生成共享库。我添加了一些较小的东西,因为我想测试一些东西。以下是ma源代码:

strong文本

#ifndef foo_h__
#define foo_h__

void foo(void);

class CFoo
{
public:
    void fooing1();
    void fooing2(int a);
    void fooing3(int a, int b = 0);
};

#endif      // foo_h__
g++ -c -Wall -Werror -fpic foo.cpp
g++ -shared -o libfoo.so foo.o
g++ -Wall -o test main.c -lfoo -L.
foo.cpp

#include <stdio.h>
#include "foo.h"

void foo(void)
{
    puts("Hello, I'm a shared library");
}

void CFoo::fooing1()
{
    puts("CFoo::fooing1()");
}

void CFoo::fooing2(int a)
{
    printf("CFoo::fooing2(%d)\n", a);
}

void CFoo::fooing3(int a, int b)
{
    printf("CFoo::fooing3(%d, %d)\n", a, b);
}
键入命令
nm-D libfoo.so | c++filt
时,我得到以下输出:

 0000000000201040 B __bss_start
                  w __cxa_finalize
 0000000000201040 D _edata
 0000000000201048 B _end
 0000000000000818 T _fini
                  w __gmon_start__
 0000000000000640 T _init
                  w _ITM_deregisterTMCloneTable
                  w _ITM_registerTMCloneTable
                  w _Jv_RegisterClasses
                  U printf
                  U puts
 0000000000000796 T foo()
 00000000000007a8 T CFoo::fooing1()
 00000000000007c2 T CFoo::fooing2(int)
 00000000000007ea T CFoo::fooing3(int, int)
我有两个问题:

1) 为什么
printf
put
的函数名前面有一个
U
?函数
foo()
CFoo::fooing1()
CFoo::fooing2(int)
CFoo::fooing3(int,int)
的函数名前是否有一个
T

2) 如何在
CFoo
函数之前获得
U

在您生成的库代码中,符号
printf
put
未定义。这是正常的,因为它们是在另一个共享库中定义的

字母T表示代码在库文件中定义(文本部分实际上与代码相对应;不得与数据部分混淆)

如果CFoo函数是共享库的核心内容,那么最好避免在库中使用U。如果您仍然希望实现这一目标:

  • 将此
    CFoo
    函数保留在类标题中声明
  • foo.cpp
    中完全删除其:代码将编译,但函数丢失(即,在库文件中根本没有定义)
  • 但是从
    foo.cpp
    中的另一个
    CFoo
    函数调用此函数:代码将编译,这次库文件将此函数定义为U:需要一个定期声明的符号,但尚未找到
我需要将
CFoo
函数设置为
U
,因为我想生成一个我遇到的问题的小示例。您应该已经阅读了手册页面。您可以使用
-C |--demangle
nm
选项,而不是通过
C++filt
管道。
 0000000000201040 B __bss_start
                  w __cxa_finalize
 0000000000201040 D _edata
 0000000000201048 B _end
 0000000000000818 T _fini
                  w __gmon_start__
 0000000000000640 T _init
                  w _ITM_deregisterTMCloneTable
                  w _ITM_registerTMCloneTable
                  w _Jv_RegisterClasses
                  U printf
                  U puts
 0000000000000796 T foo()
 00000000000007a8 T CFoo::fooing1()
 00000000000007c2 T CFoo::fooing2(int)
 00000000000007ea T CFoo::fooing3(int, int)