【问题标题】:How are these MySQL classes able to link?这些 MySQL 类是如何链接的?
【发布时间】:2016-03-18 19:51:54
【问题描述】:

在内置 MySQL 存储引擎的实现中,存在具有以下结构的类:

// omitting lots of code across several files
class handler {
   protected:
      virtual void notify_table_changed();
};

void handler::notify_table_changed() {
   // implementation
}

class ha_innopart : public handler {
   void notify_table_changed();
};

// NB: no implementation for ha_innopart!

据我了解,这应该会给出一个链接错误,因为ha_innopart 将缺少notify_table_changed() 的 vtable 条目。这是supported by the gcc FAQ。

相关 MySQL 类的链接:

以下代码重现了我所看到的问题:

#include <stdio.h>

class A {
   public:
      virtual int foo();
};

class B : public A {
   public:
      int foo();               // Will work by commenting out this line...
};

int A::foo() { return 42; }
// int B::foo() { return 24; } // ...or uncommenting this line.

int main(int argc, char **argv) {
   B b;
   ::printf("%d\n", b.foo());
}

编译得到:

$ g++ test.cc -o test && ./test
/tmp/ccAiCHry.o: In function `main':
test.cc:(.text+0x32): undefined reference to `B::foo()'
/tmp/ccAiCHry.o: In function `B::B()':
test.cc:(.text._ZN1BC2Ev[_ZN1BC5Ev]+0x1f): undefined reference to `vtable for B'
collect2: ld returned 1 exit status

如上述 cmets 所述,可以通过注释掉 B 的 foo() 声明或为 B 提供 foo() 的实现来解决此问题。这些案例的输出分别是:

$ !!
g++ test.cc -o test && ./test
42
$ !!
g++ test.cc -o test && ./test
24

那么,MySQL没有实现ha_innopart::notify_table_changed(),怎么还能编译链接不出错呢?

【问题讨论】:

  • 它要么未使用,要么在库中。拿一个使用它的程序,查看链接它的库,然后遍历库中的符号,直到找到它。像“nm”这样的东西会帮助你sourceware.org/binutils/docs/binutils/nm.html

标签: c++ mysql gcc linker g++


【解决方案1】:

事实证明,ha_innopart 的实现被分解为多个文件,并且该实现确实存在:

我在搜索用途时找到了实现。

https://github.com/mysql/mysql-server/search?utf8=%E2%9C%93&q=notify_table_changed

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-04-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多