我写了一个动态库
libsort.so
并隐式连接它。然后我通过键盘明确连接它。编译后,出现错误undefined symbol
。文件sort.cpp
和sort.h
是动态库的来源,example.cpp
这是我连接库的程序。
// sort.cpp
#include <bits/stdc++.h>
#include <iostream>
void merge(int array[], int const left, int const mid, int const right) {
int const subArrayOne = mid - left + 1;
int const subArrayTwo = right - mid;
auto *leftArray = new int[subArrayOne], *rightArray = new int[subArrayTwo];
for (auto i = 0; i < subArrayOne; i++)
leftArray[i] = array[left + i];
for (auto j = 0; j < subArrayTwo; j++)
rightArray[j] = array[mid + 1 + j];
auto indexOfSubArrayOne = 0, indexOfSubArrayTwo = 0;
int indexOfMergedArray = left;
while (indexOfSubArrayOne < subArrayOne && indexOfSubArrayTwo < subArrayTwo) {
if (leftArray[indexOfSubArrayOne] <= rightArray[indexOfSubArrayTwo]) {
array[indexOfMergedArray] = leftArray[indexOfSubArrayOne];
indexOfSubArrayOne++;
} else {
array[indexOfMergedArray] = rightArray[indexOfSubArrayTwo];
indexOfSubArrayTwo++;
}
indexOfMergedArray++;
}
while (indexOfSubArrayOne < subArrayOne) {
array[indexOfMergedArray] = leftArray[indexOfSubArrayOne];
indexOfSubArrayOne++;
indexOfMergedArray++;
}
while (indexOfSubArrayTwo < subArrayTwo) {
array[indexOfMergedArray] = rightArray[indexOfSubArrayTwo];
indexOfSubArrayTwo++;
indexOfMergedArray++;
}
delete[] leftArray;
delete[] rightArray;
}
void mergeSort(int array[], int const begin, int const end) {
if (begin >= end)
return;
int mid = begin + (end - begin) / 2;
mergeSort(array, begin, mid);
mergeSort(array, mid + 1, end);
merge(array, begin, mid, end);
}
void printArray(int A[], int size) {
for (int i = 0; i < size; i++)
std::cout << A[i] << " ";
std::cout << std::endl;
}
int rand_int(int min, int max) {
std::random_device rd;
std::mt19937 gen(rd());
std::uniform_int_distribution<int> dist(min, max);
return dist(gen);
}
// sort.h
void merge(int array[], int const left, int const mid, int const right);
void mergeSort(int array[], int const begin, int const end);
void printArray(int A[], int size);
int rand_int(int min, int max);
// example.cpp
#include <dlfcn.h>
#include <iostream>
int main(int argc, char *argv[]) {
int (*rand)(int, int);
void (*print_arr)(int[], int);
void (*merge_s)(int[], int, int);
void *ext_library = dlopen("/home/nikita/C++/shared/libsort.so", RTLD_LAZY);
if (!ext_library) {
std::cerr << "Error loading library: " << dlerror() << std::endl;
return 1;
}
rand = (int (*)(int, int))dlsym(ext_library, "rand_int");
print_arr = (void (*)(int[], int))dlsym(ext_library, "printArray");
merge_s = (void (*)(int[], int, int))dlsym(ext_library, "mergeSort");
if (!print_arr || !merge_s || !rand) {
std::cerr << "Error loading symbols: " << dlerror() << std::endl;
dlclose(ext_library);
return 1;
}
int n = rand(5, 25);
int *arr = new int[n];
print_arr(arr, n);
merge_s(arr, 0, n - 1);
print_arr(arr, n);
dlclose(ext_library);
return 0;
}
example.cpp
我用命令g++ example.cpp -o example -ldl
编译。我使用命令 ./example
运行它,然后出现错误 Error loading symbols: /home/nikita/C++/shared/libsort.so: undefined symbol: mergeSort
我尝试将编译器改为clang,编译依然成功,但是运行./example时,错误依旧。
我使用 extern C 重写了库源代码,之后一切正常。
// sort.cpp
#include <bits/stdc++.h>
#include <iostream>
#ifdef __cplusplus
extern "C" {
#endif
void merge(int array[], int const left, int const mid, int const right) {
int const subArrayOne = mid - left + 1;
int const subArrayTwo = right - mid;
auto *leftArray = new int[subArrayOne], *rightArray = new int[subArrayTwo];
for (auto i = 0; i < subArrayOne; i++)
leftArray[i] = array[left + i];
for (auto j = 0; j < subArrayTwo; j++)
rightArray[j] = array[mid + 1 + j];
auto indexOfSubArrayOne = 0, indexOfSubArrayTwo = 0;
int indexOfMergedArray = left;
while (indexOfSubArrayOne < subArrayOne && indexOfSubArrayTwo < subArrayTwo) {
if (leftArray[indexOfSubArrayOne] <= rightArray[indexOfSubArrayTwo]) {
array[indexOfMergedArray] = leftArray[indexOfSubArrayOne];
indexOfSubArrayOne++;
} else {
array[indexOfMergedArray] = rightArray[indexOfSubArrayTwo];
indexOfSubArrayTwo++;
}
indexOfMergedArray++;
}
while (indexOfSubArrayOne < subArrayOne) {
array[indexOfMergedArray] = leftArray[indexOfSubArrayOne];
indexOfSubArrayOne++;
indexOfMergedArray++;
}
while (indexOfSubArrayTwo < subArrayTwo) {
array[indexOfMergedArray] = rightArray[indexOfSubArrayTwo];
indexOfSubArrayTwo++;
indexOfMergedArray++;
}
delete[] leftArray;
delete[] rightArray;
}
void mergeSort(int array[], int const begin, int const end) {
if (begin >= end)
return;
int mid = begin + (end - begin) / 2;
mergeSort(array, begin, mid);
mergeSort(array, mid + 1, end);
merge(array, begin, mid, end);
}
void printArray(int A[], int size) {
for (int i = 0; i < size; i++)
std::cout << A[i] << " ";
std::cout << std::endl;
}
int rand_int(int min, int max) {
std::random_device rd;
std::mt19937 gen(rd());
std::uniform_int_distribution<int> dist(min, max);
return dist(gen);
}
#ifdef __cplusplus
}
#endif
// sort.h
#ifdef __cplusplus
extern "C" {
#endif
void merge(int array[], int const left, int const mid, int const right);
void mergeSort(int array[], int const begin, int const end);
void printArray(int A[], int size);
int rand_int(int min, int max);
#ifdef __cplusplus
}
#endif
// example.cpp
#include <dlfcn.h>
#include <iostream>
#include <ostream>
int main(int argc, char *argv[]) {
int (*rand)(int, int);
void (*print_arr)(int[], int);
void (*merge_s)(int[], int, int);
void *ext_library = dlopen("/home/nikita/C++/shared/libsort.so", RTLD_LAZY);
if (!ext_library) {
std::cerr << "Error loading library: " << dlerror() << std::endl;
return 1;
}
rand = (int (*)(int, int))dlsym(ext_library, "rand_int");
print_arr = (void (*)(int[], int))dlsym(ext_library, "printArray");
merge_s = (void (*)(int[], int, int))dlsym(ext_library, "mergeSort");
if (!print_arr || !merge_s || !rand) {
std::cerr << "Error loading symbols: " << dlerror() << std::endl;
dlclose(ext_library);
return 1;
}
int n = rand(5, 25);
int *arr = new int[n];
for (int i = 0; i < n; i++)
*(arr + i) = rand(-100, 100);
std::cout << "Исходный массив: " << std::endl;
print_arr(arr, n);
merge_s(arr, 0, n - 1);
std::cout << "Отсортированный масиив: " << std::endl;
print_arr(arr, n);
dlclose(ext_library);
return 0;
}
显然,函数名称已被 C++ 编译器进行了“名称修改”过程。我使用“extern C”修复了这个错误。