2011-09-05 38 views
-1

我: car.cc共享庫如何鏈接到一個符號?

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

using namespace std; 


extern "C" Car* create_object() 
{ 
    return new Car; 
} 


Car::Car() { 
    this->maxGear = 2; 
    this->currentGear = 1; 
    this->speed = 0; 
} 

void Car::shift(int gear) { 
    if (gear < 1 || gear > maxGear) { 
     return; 
    } 
    currentGear = gear; 
} 


void Car::brake() { 
    speed -= (5 * this->getCurrentGear()); 
    std::cout<<"THE SPEED IS:" <<speed<<std::endl; 
} 


extern "C" void destroy_object(Car* object) 
{ 
    delete object; 
} 

car.h

#ifndef VEHICLES_CAR_H 
#define VEHICLES_CAR_H 

// A very simple car class 
class Car { 
public: 
    Car(); 
    void shift(int gear); 
    void accelerate(); 
    void brake(); 

private: 
    int maxGear; 
    int currentGear; 
    int speed; 
}; 

#endif /* VEHICLES_CAR_H */ 

test.cc

#include "/home/car.h" 
#include <dlfcn.h> 
#include <stdio.h> 
#include <stdlib.h> 
#include <iostream> 

using namespace std; 

int main() 
{ 
    /* on Linux, use "./myclass.so" */ 
    void* handle = dlopen("/usr/lib/libCarTest.so", RTLD_LAZY); 
    int (*result)(int); 
if (!handle) 
{ 

} 

/*dlsym(handle,"accelerate"); 
cout<<"IN HERE: "<<endl; 
dlsym(handle,"brake"); 
dlclose(handle);*/ 
Car* (*create)(); 
    void (*destroy)(Car*); 
dlerror(); 
    create = (Car* (*)())dlsym(handle, "create_object"); 
    destroy = (void (*)(Car*))dlsym(handle, "destroy_object"); 

    Car* carr = (Car*)create(); 
    carr->brake(); 

    destroy(carr); 
    dlclose(handle); 

/* 
Car carr; 
carr.brake(); 
* compilation g++ test.cpp -o tst /path/libcar.so 
*/ 
return 0; 
} 

創建libMyLib.so/usr/lib安裝它,我已經試過編譯後test.cc使用:g++ test.cc -o tst -ldl。爲什麼我需要包含-lMyLib?有沒有辦法在沒有libMyLib.so的情況下編譯代碼?其次爲什麼dlsym(handle,"brake")不工作?如果我改變的dlsym(轎車*(*)......與dlsym(handle,"brake")我什麼也沒有。爲什麼?

欣賞

回答

3

爲什麼我需要包括-lmylib?

因爲你需要鏈接到Car::brake方法。

其次,爲什麼對dlsym(手柄, 「剎車」)不工作?

因爲沒有brake符號。方法Car::brake有一個複雜的(實現定義的)名稱。你可以在nm -D的輸出中看到這個。

AFAIK,您可以通過

  • 使得Car虛擬所有的方法解決它(他們會通過一個指針調用,這樣不就可以把鏈接)
  • 做舊的C方式,即。導出一個免費函數brake(),這個函數將調用Car::brake方法.so
  • 使所有的公共方法Carinline並在標題中定義它們。
  • 模擬虛表的方法(如我們做它在C)

最後兩個方法結合起來:

class Car { 
public: 
    void brake() { brake_impl(this); } 
private: 
    void (*brake_impl)(Car*); 
    void do_brake(); // this would be the actual implementation 
    Car() : brake_impl([] (Car* c){ c->do_brake(); }) { ... } 
}; 

當然,你可能分裂的實施和接口,所以它不是這樣的一塌糊塗。