I have written a dynamic library libsort.so
and connected it implicitly. Then I connected it explicitly through the keyboard. After compiling, I got the error undefined symbol
. The file sort.cpp
and sort.h
are the sources of the dynamic library, example.cpp
this is the program that I have connected the library to.
// 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
I compiled with the command g++ example.cpp -o example -ldl
. I run it with the command ./example
, then I got an error
Error loading symbols: /home/nikita/C++/shared/libsort.so: undefined symbol: mergeSort
I tried to change the compiler to clang, compilation is still successful, but when running ./example
, the error remains the same.
I rewrote the library sources using extern C
, after which everything worked fine.
// 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;
}
Apparently, the function names have been subjected to the "name mangling" process by the C++ compiler. I fixed this error using extern C
.