简体   繁体   English

共享库如何链接到符号?

[英]shared library how to link to a symbol?

I have: car.cc 我有: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;   
}

After creating libMyLib.so and install it in /usr/lib i've tried to compile test.cc using: g++ test.cc -o tst -ldl . 创建libMyLib.so并将其安装在/usr/lib我尝试使用以下命令编译test.cc:g g++ test.cc -o tst -ldl WHY do i need to include -lMyLib? 为什么需要包含-lMyLib? is there a way to compile the code without libMyLib.so ? 没有libMyLib.so有没有办法编译代码? Secondly why dlsym(handle,"brake") is not working? 其次,为什么dlsym(handle,"brake")不起作用? If i change dlsym (Car* (*).... with dlsym(handle,"brake") i get nothing. why? 如果我用dlsym(handle,"brake")更改dlsym(Car *(*).... dlsym(handle,"brake")我什么也没得到,为什么?

Appreciate 欣赏

WHY do i need to include -lMyLib? 为什么需要包含-lMyLib?

Because you need to link to the Car::brake method. 因为您需要链接到Car::brake方法。

Secondly why dlsym(handle,"brake") is not working? 其次,为什么dlsym(handle,“ brake”)不起作用?

Because there is no brake symbol. 因为没有brake标志。 The method Car::brake has a complicated mangled (implementation-defined) name. Car::brake方法具有复杂的(由实现定义的)名称。 You can see this in the output of nm -D . 您可以在nm -D的输出中看到这一点。

AFAIK, you can solve it by AFAIK,您可以通过解决

  • making all the methods of Car virtual (they will be called through a pointer, so no linking will be needed) Car所有方法虚拟化(它们将通过指针被调用,因此不需要链接)
  • doing it the old C way, ie. 用旧的C方式做,即。 export a free function brake() that would call the Car::brake method from the .so 导出一个自由函数brake() ,该Car::brake将从.so调用Car::brake方法
  • making all the public methods of Car inline and defining them in the header. 使Car所有公共方法inline ,并在标题中定义它们。
  • emulating the virtual table approach (as we do it in C) 模拟虚拟表方法(就像我们在C中所做的那样)

Combining the last two approaches: 结合最后两种方法:

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(); }) { ... }
};

Of course you could split the implementation and the interface so it's not such a mess. 当然,您可以拆分实现和接口,因此不会造成混乱。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM