1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134
| #include <stdio.h> #include <stdlib.h> #include <dlfcn.h> // 动态加载库函数
// 定义函数指针类型,用于从动态库中获取的函数 typedef int (*add_func_t)(int, int); typedef int (*multiply_func_t)(int, int); typedef void (*print_func_t)(const char*);
int main() { void* handle = NULL; char* error = NULL; printf("=== 动态链接库示例程序 ===\n\n"); // 1. 使用 dlopen 打开共享库 printf("1. 正在加载共享库 'libmymath.so'...\n"); handle = dlopen("./libmymath.so", RTLD_LAZY); if (!handle) { fprintf(stderr, "错误: 无法加载库: %s\n", dlerror()); return EXIT_FAILURE; } printf(" √ 库加载成功!\n\n"); // 2. 清除之前的错误状态 dlerror(); // 3. 使用 dlsym 获取库中的函数地址 printf("2. 正在从库中获取函数地址...\n"); // 获取 add 函数 // int (*my_add)(int, int) = (int (*)(int, int))dlsym(handle,"add"); add_func_t my_add = (add_func_t)dlsym(handle, "add"); if ((error = dlerror()) != NULL) { fprintf(stderr, "错误: 找不到 add 函数: %s\n", error); dlclose(handle); return EXIT_FAILURE; } printf(" √ 找到 add 函数\n"); // 获取 multiply 函数 multiply_func_t my_multiply = (multiply_func_t)dlsym(handle, "multiply"); if ((error = dlerror()) != NULL) { fprintf(stderr, "错误: 找不到 multiply 函数: %s\n", error); dlclose(handle); return EXIT_FAILURE; } printf(" √ 找到 multiply 函数\n"); // 获取 print_message 函数 print_func_t my_print = (print_func_t)dlsym(handle, "print_message"); if ((error = dlerror()) != NULL) { fprintf(stderr, "错误: 找不到 print_message 函数: %s\n", error); dlclose(handle); return EXIT_FAILURE; } printf(" √ 找到 print_message 函数\n"); // 4. 获取库中的变量 printf("\n3. 正在从库中获取变量...\n"); // 获取 library_name 变量 const char** lib_name_ptr = (const char**)dlsym(handle, "library_name"); if ((error = dlerror()) != NULL) { fprintf(stderr, "警告: 找不到 library_name 变量: %s\n", error); } else { printf(" √ 库名称: %s\n", *lib_name_ptr); } // 获取 version_major 变量 const int* ver_major_ptr = (const int*)dlsym(handle, "version_major"); if ((error = dlerror()) != NULL) { fprintf(stderr, "警告: 找不到 version_major 变量: %s\n", error); } else { printf(" √ 主版本号: %d\n", *ver_major_ptr); } // 获取 version_minor 变量 const int* ver_minor_ptr = (const int*)dlsym(handle, "version_minor"); if ((error = dlerror()) != NULL) { fprintf(stderr, "警告: 找不到 version_minor 变量: %s\n", error); } else { printf(" √ 次版本号: %d\n", *ver_minor_ptr); } // 5. 使用动态加载的函数 printf("\n4. 调用动态加载的函数...\n"); int result; // 调用 add 函数 result = my_add(10, 5); printf(" add(10, 5) = %d\n", result); // 调用 multiply 函数 result = my_multiply(10, 5); printf(" multiply(10, 5) = %d\n", result); // 调用 print_message 函数 my_print("Hello from main program!"); // 6. 关闭库 printf("\n5. 清理资源...\n"); if (dlclose(handle) != 0) { fprintf(stderr, "警告: 关闭库时出错: %s\n", dlerror()); } else { printf(" √ 库已成功关闭\n"); } // 7. 演示 RTLD_NOW 标志的使用 printf("\n6. 演示 RTLD_NOW 标志...\n"); handle = dlopen("./libmymath.so", RTLD_NOW); if (!handle) { fprintf(stderr, "错误: 无法用 RTLD_NOW 加载库: %s\n", dlerror()); } else { printf(" √ 使用 RTLD_NOW 加载成功\n"); dlclose(handle); } // 8. 演示加载不存在的库 printf("\n7. 演示错误处理(加载不存在的库)...\n"); handle = dlopen("./nonexistent_lib.so", RTLD_LAZY); if (!handle) { fprintf(stderr, " × 预期错误: %s\n", dlerror()); } else { printf(" √ 不应该执行到这里\n"); dlclose(handle); } printf("\n=== 程序执行完毕 ===\n"); return EXIT_SUCCESS; }
|