본문 바로가기
개발 및 운영/C++

공유 라이브러리에서 C++ 다형성 사용

by Joseph.Lee 2021. 3. 10.

버전 업그레이드시 클래스를 변경해도 안전하게 사용할 수 있는 라이브러리를 만들고 싶었다. (ABI 호환)

그런데 방법이 생각이...

모든 메서드에 대해 invoke 함수를 통해 실행하도록 해야하나..

간편한 방법은 없는 듯 하다.

 

상속 및 다형성으로 vtable를 통한 호출 방법을 테스트 해 본 것이다.

Disassembly of section .text:

0000000000000000 <main>:
class B : public A {
public:
  void hello() override;
};

int main() {
   0:   f3 0f 1e fa             endbr64
   4:   55                      push   %rbp
   5:   48 89 e5                mov    %rsp,%rbp
   8:   48 83 ec 10             sub    $0x10,%rsp
  A* a = (A*)0x10000;
   c:   48 c7 45 f0 00 00 01    movq   $0x10000,-0x10(%rbp)
  13:   00
  B* b = (B*)0x20000;
  14:   48 c7 45 f8 00 00 02    movq   $0x20000,-0x8(%rbp)
  1b:   00

  a->hello();
  1c:   48 8b 45 f0             mov    -0x10(%rbp),%rax      rax = a
  20:   48 8b 00                mov    (%rax),%rax           rax = *rax (= vptr = a)
  23:   48 8b 10                mov    (%rax),%rdx           rdx = *rax (vtable = *vptr)
  26:   48 8b 45 f0             mov    -0x10(%rbp),%rax      rax = a
  2a:   48 89 c7                mov    %rax,%rdi             rdi = rax = a (this pointer)
  2d:   ff d2                   callq  *%rdx                 call *rdx     (vtable[0])
  a->world();
  2f:   48 8b 45 f0             mov    -0x10(%rbp),%rax      rax = a
  33:   48 8b 00                mov    (%rax),%rax           rax = *rax (= vptr = a)
  36:   48 83 c0 08             add    $0x8,%rax             rax += 8
  3a:   48 8b 10                mov    (%rax),%rdx           rdx = rax  (vtable + 8 = *vptr + 8)
  3d:   48 8b 45 f0             mov    -0x10(%rbp),%rax      rax = a
  41:   48 89 c7                mov    %rax,%rdi             rdi = rax = a (this pointer)
  44:   ff d2                   callq  *%rdx                 call *rdx     (vtable[1])
  b->hello();
  46:   48 8b 45 f8             mov    -0x8(%rbp),%rax       rax = b
  4a:   48 8b 00                mov    (%rax),%rax           rax = *rax (= vptr = b)
  4d:   48 8b 10                mov    (%rax),%rdx           rdx = *rax (= *vptr)
  50:   48 8b 45 f8             mov    -0x8(%rbp),%rax       rax = b
  54:   48 89 c7                mov    %rax,%rdi             rdi = rax = b (this pointer)
  57:   ff d2                   callq  *%rdx                 call *rdx     (vtable[0])
  b->world();
  59:   48 8b 45 f8             mov    -0x8(%rbp),%rax       rax = b
  5d:   48 8b 55 f8             mov    -0x8(%rbp),%rdx       rdx = b    (= vptr = b)
  61:   48 8b 12                mov    (%rdx),%rdx           rdx = *rdx (= *vptr)
  64:   48 83 c2 08             add    $0x8,%rdx             rdx += 8
  68:   48 8b 12                mov    (%rdx),%rdx           rdx = *rdx
  6b:   48 89 c7                mov    %rax,%rdi             rdi = rax = b (this pointer)
  6e:   ff d2                   callq  *%rdx                 call *rdx     (vtable[1])

  return 0;
  70:   b8 00 00 00 00          mov    $0x0,%eax
}
  75:   c9                      leaveq
  76:   c3                      retq

만약 인터페이스에서 메서드의 순서가 달라지면 같은 메서드였어도 순서 바뀜으로 인해 다른 메서드가 호출되게 된다.

 

 

참고:

stackoverflow.com/questions/57999911/is-it-safe-to-use-polymorphic-objects-from-a-shared-library

 

Is it safe to use polymorphic objects from a shared library?

I have an interface, and I have an implementation of that interface in a shared library, and who knows what it was compiled with. dynamic_cast works only on polymorphic types. So I can assume it d...

stackoverflow.com

 

반응형

'개발 및 운영 > C++' 카테고리의 다른 글

Clion "Cannot create directory" 오류  (0) 2020.08.20

댓글