2011-09-05 77 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(); }) { ... } 
}; 

当然,你可能分裂的实施和接口,所以它不是这样的一塌糊涂。