tl;博士
dlopen當主應用程式通過and使用動態庫時dlsym,是否需要以任何方式鏈接它?
假設我有一個這樣的圖書館,
- 標題
#pragma once void foo(); - 執行
#include "MyLib.hpp" #include <iostream> void foo() { std::cout << "Hello world, dynamic library speaking" << std::endl; }
我編譯通過
g -fPIC -shared MyLib.cpp -o libMyLib.so
如果主應用程式只是使用該庫匯出的符號,例如
#include "MyLib.hpp"
#include <iostream>
int main() {
int x;
std::cin >> x;
std::cout << "before calling foo" << std::endl;
foo();
}
這意味著我必須將它與圖書館聯系起來,即
g -c main.cpp -o main.o
g -L. -lMyLib main.o -o main
有兩件事讓我感到困惑:
第一個是:為什么我需要鏈接
main.o反對libMyLib.so?我的意思是,標頭MyLib.hpp已經提供main.cpp了foo. 在這種情況下,鏈接的作用是什么?那么主應用程式
dlopen用來加載庫并dlsym從其中加載符號的情況又如何呢?我的理解是它仍然需要
#include "MyLib.hpp",因為它需要知道如何解釋的輸出dlsym,但main.o無論如何都需要與共享物件鏈接?
uj5u.com熱心網友回復:
如果您使用dlopen并且dlsym不需要頭檔案或foo函式原型。您不需要它,因為庫中的名稱不會是 plain foo。
C 編譯器使用名稱修飾來處理函式多載之類的事情,并且它是您需要傳遞的修飾dlsym名稱以獲取指向函式的指標。損壞的名稱是非常特定于實作的,您需要檢查庫以找出實際的損壞名稱。
作為名稱修改問題的解決方法,您可以將庫中的函式宣告為extern "C". 除其他外,這將禁止名稱修改,您可以將名稱傳遞foo給dlsym.
此外,如果您使用dlopen并且dlsym不應該與庫鏈接。這違背了您的應用程式執行動態鏈接的目的。
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/513867.html
下一篇:單擊時選擇和取消選擇(其他)按鈕
