Bạn có hai lựa chọn, từ đó bạn có thể chọn:
Lựa chọn 1: xuất khẩu tất cả các biểu tượng từ thực thi của bạn. Đây là tùy chọn đơn giản, chỉ khi xây dựng tệp thực thi, hãy thêm cờ -Wl,--export-dynamic
. Điều này sẽ làm cho tất cả các chức năng có sẵn cho các cuộc gọi thư viện.
Tùy chọn 2: tạo tệp biểu tượng xuất với danh sách hàm và sử dụng -Wl,--dynamic-list=exported.txt
. Điều này đòi hỏi một số bảo trì, nhưng chính xác hơn.
Để minh họa: thư viện thực thi và tải động đơn giản.
#include <stdio.h>
#include <dlfcn.h>
void exported_callback() /*< Function we want to export */
{
printf("Hello from callback!\n");
}
viud unexported_callback() /*< Function we don't want to export */
{
printf("Hello from unexported callback!\n");
}
typedef void (*lib_func)();
int call_library()
{
void *handle = NULL;
lib_func func = NULL;
handle = dlopen("./libprog.so", RTLD_NOW | RTLD_GLOBAL);
if (handle == NULL)
{
fprintf(stderr, "Unable to open lib: %s\n", dlerror());
return -1;
}
func = dlsym(handle, "library_function");
if (func == NULL) {
fprintf(stderr, "Unable to get symbol\n");
return -1;
}
func();
return 0;
}
int main(int argc, const char *argv[])
{
printf("Hello from main!\n");
call_library();
return 0;
}
Mã thư viện (lib.c):
#include <stdio.h>
int exported_callback();
int library_function()
{
printf("Hello from library!\n");
exported_callback();
/* unexported_callback(); */ /*< This one will not be exported in the second case */
return 0;
}
Vì vậy, lần đầu tiên xây dựng thư viện (bước này không khác nhau):
gcc -shared -fPIC lib.c -o libprog.so
Bây giờ xây dựng thực thi với tất cả những biểu tượng xuất khẩu:
gcc -Wl,--export-dynamic main.c -o prog.exe -ldl
Run dụ:
$ ./prog.exe
Hello from main!
Hello from library!
Hello from callback!
Biểu tượng hiển thị rted:
$ objdump -e prog.exe -T | grep callback
00000000004009f4 g DF .text 0000000000000015 Base exported_callback
0000000000400a09 g DF .text 0000000000000015 Base unexported_callback
Bây giờ với danh sách xuất khẩu (exported.txt
):
{
extern "C"
{
exported_callback;
};
};
Build & kiểm tra những biểu tượng có thể nhìn thấy:
$ gcc -Wl,--dynamic-list=./exported.txt main.c -o prog.exe -ldl
$ objdump -e prog.exe -T | grep callback
0000000000400774 g DF .text 0000000000000015 Base exported_callback
Tôi muốn làm 'if (callback) {callback(); trả về 0; } else {return -1; } 'để chỉ ra một lỗi và để tránh gọi' NULL' (mà sẽ gây tử vong). – glglgl
Phải, đã xóa đường nét. – user746527