2017-06-01 15 views
0

私はdlopenを使用するときに共有ライブラリにリンクする必要はありません。 cmakeのにリンカエラーでtarget_link_libraries(main_dlopen dl)結果dlopenを使用している場合は、私が開いたライブラリとリンクする必要がありますか?

main_dlopen.cpp.o: In function `main': 
main_dlopen.cpp:25: undefined reference to `ntclass::init(char const*)' 
etc... 

私はlibntclass.soは私のライブラリであるtarget_link_libraries(main_dlopen dl ntclass)を、使用している場合しかし、その後、すべてが正常です。

本当にうまいですか、何か不足していますか?背景として、私はhereで説明されているように、スレッドセーフではないライブラリをテストしたいと思います。また、スレッドセーフでないライブラリではリンクを避ける必要があります。 は、部分的に完全な例は、(参照としてthisを使用)以下である

下に自分自身に答え。

(共有ライブラリ)

ntclass.h

#ifndef NTCLASS_H 
#define NTCLASS_H 

#include <cstddef> 

class ntclass 
{ 
    private: 
    static char *sptr; 
    char *ptr; 

    public: 
    ntclass() : ptr(NULL) {} 
    ~ntclass(); 

    void init(const char* str); 
    void print(); 
}; 

typedef ntclass* create_t(); 

#endif // NTCLASS_H 

ntclass.cpp

#include "ntclass.h" 
#include <stdio.h> 
#include <string.h> 
#include <iostream> 

char *gptr = NULL; 

char *ntclass::sptr = NULL; 

ntclass::~ntclass() 
{ 
    if (gptr) 
    { 
    delete[] gptr; 
    gptr = NULL; 
    } 
    if (sptr) 
    { 
    delete[] sptr; 
    sptr = NULL; 
    } 
    if (ptr) 
    { 
    delete[] ptr; 
    ptr = NULL; 
    } 
} 

void ntclass::init(const char* str) 
{ 
    int size = strlen(str)*sizeof(char); 
    gptr = new char[size]; 
    memcpy(gptr, str, size); 
    sptr = new char[size]; 
    memcpy(sptr, str, size); 
    ptr = new char[size]; 
    memcpy(ptr, str, size); 
} 

void ntclass::print() 
{ 
    std::cout << "Global: " << gptr << std::endl; 
    std::cout << "Static: " << sptr << std::endl; 
    std::cout << "Normal: " << ptr << std::endl; 
} 

extern "C" ntclass *create() 
{ 
    return new ntclass(); 
} 

(メインの実行)

main_dlopen.cpp

#include <iostream> 
#include "ntclass.h" 

#include <dlfcn.h> 
#include <stdlib.h> 

using namespace std; 

int main() 
{ 
    void *handle = dlopen("./libntclass.so", RTLD_NOW); 

    if (handle == NULL) 
    { 
    cerr << dlerror() << endl; 
    exit(-1); 
    } 

    create_t *createA = (create_t*) dlsym(handle, "create"); 
    create_t *createB = (create_t*) dlsym(handle, "create"); 

    ntclass *A = createA(); 
    ntclass *B = createB(); 

    A->init("A"); 
    B->init("B"); 

    A->print(); 
    B->print(); 

    delete A; 
    delete B; 

    return 0; 
} 

(cmakeの)

cmake_minimum_required(VERSION 2.8) 

set(CMAKE_VERBOSE_MAKEFILE on) 
set(CMAKE_BUILD_TYPE RelWithDebInfo) 

add_library(ntclass SHARED ntclass.cpp) 

add_executable(main_dlopen main_dlopen.cpp) 
target_link_libraries(main_dlopen dl) # <-- Here is a problem 

部分的な答え: 私はntclassメソッドのキーワードvirtual(INIT、印刷、〜ntclass)を添加し、それが今で正常に動作します。それでも誰もがなぜ必要なのか説明できますか?

答えて

1

「部分回答」は正しい修正です。説明については、that nice answervirtualキーワードを参照してください。要するに

ntclassinit方法は、仮想として宣言され

まで、発現

A->init("A") 

は、そのクラスに(独立した方法の定義を使用する実際の型にオブジェクトA)。 main_dlopen.cppにこの定義がないため、リンカはエラーを生成します。 virtualキーワードで

は、init方法の分解能はAオブジェクトの実際の型が知られているであろうと、ランタイムするdefferedれます。

+0

ありがとうございます、今はっきりしています。 – Ivan

関連する問題