簡體   English   中英

共享庫如何鏈接到符號?

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

我有: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;
}

#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 */

測試文件

#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 g++ test.cc -o tst -ldl 為什么需要包含-lMyLib? 沒有libMyLib.so有沒有辦法編譯代碼? 其次,為什么dlsym(handle,"brake")不起作用? 如果我用dlsym(handle,"brake")更改dlsym(Car *(*).... dlsym(handle,"brake")我什么也沒得到,為什么?

欣賞

為什么需要包含-lMyLib?

因為您需要鏈接到Car::brake方法。

其次,為什么dlsym(handle,“ brake”)不起作用?

因為沒有brake標志。 Car::brake方法具有復雜的(由實現定義的)名稱。 您可以在nm -D的輸出中看到這一點。

AFAIK,您可以通過解決

  • Car所有方法虛擬化(它們將通過指針被調用,因此不需要鏈接)
  • 用舊的C方式做,即。 導出一個自由函數brake() ,該Car::brake將從.so調用Car::brake方法
  • 使Car所有公共方法inline ,並在標題中定義它們。
  • 模擬虛擬表方法(就像我們在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(); }) { ... }
};

當然,您可以拆分實現和接口,因此不會造成混亂。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM