2014-02-20 5 views
1

У меня есть файл myLib.so и заголовочный файл USB.h. Мой заголовочный файл выглядит так, и myLib.so содержит реализацию этого файла заголовка. Как я могу использовать myLib.so для вызова функции getUsbList в моем main.cpp.C++ Как пользовательская динамическая библиотека (файл .so)

#ifndef USB_H 
#define USB_H 
#include <string.h> 
#include <string> 
#include <vector> 

vector<string> getUsbList(); 

#endif // USB_H 

Я стараюсь это, но он дает ошибку: Не удается загрузить символ 'getUsbList': myLib.so: неопределенные символ: getUsbList

#include <iostream> 
#include <dlfcn.h> 
#include "USB.h" 

int main() { 
    using std::cout; 
    using std::cerr; 

    cout << "C++ dlopen demo\n\n"; 

    // open the library 
    cout << "Opening myLib.so...\n"; 
    void* handle = dlopen("myLib.so", RTLD_LAZY); 

    if (!handle) { 
     cerr << "Cannot open library: " << dlerror() << '\n'; 
     return 1; 
    } 

    // load the symbol 
    cout << "Loading symbol myLib...\n"; 
    typedef void (*USB_t)(); 

    // reset errors 
    dlerror(); 
    USB_t getUsbList = (USB_t) dlsym(handle, "getUsbList"); 
    const char *dlsym_error = dlerror(); 
    if (dlsym_error) { 
     cerr << "Cannot load symbol 'getUsbList': " << dlsym_error << 
      '\n'; 
     dlclose(handle); 
     return 1; 
    } 

    // use it to do the calculation 
    cout << "Calling getUsbList...\n"; 
    getUsbList(); 

    // close the library 
    cout << "Closing library...\n"; 
    dlclose(handle); 
} 
+0

Вам действительно нужно вручную разрешение? Не можете ли вы просто подключиться к библиотеке (с помощью командной строки -l')? –

ответ

3

Похоже, вы используете C++

vector<string> getUsbList(); 

C++ применяет так называемое «манипулирование именем», чтобы дать каждому функциональному символу уникальное имя, основанное на типах входных и выходных параметров. Это делается для поддержки перегрузки функций (несколько функций с тем же именем, но с разными типами параметров).

Вы либо должны загружаться на основе искаженного имени, либо вам нужно отключить манипуляцию имени (и, следовательно, возможность перегрузить функцию).

Поскольку нет стандартов о том, как имена искалечены, и каждый компилятор может реализовать его по-другому, это не очень надежный метод.

Отключение имени коверкание осуществляется путем окружения объявления функций в заголовке с

extern "C" { 

// ... 

} 
+0

В случае, если исполняемая и разделяемая библиотека написана на C++, extern «C» не нужен – Peter

+2

@Peter: OP пытается загрузить символы с помощью 'dlopen', передавая неподписанное имя, которое, конечно, не может быть найдено в .so – datenwolf

+0

Вы правы, я упускаю из виду, что он использует ldopen – Peter