显式链接库的问题

问题描述 投票:0回答:1

我写了一个动态库

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时,错误依旧。

linux g++ shared-libraries dynamic-library undefined-symbol
1个回答
0
投票

我使用 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”修复了这个错误。

© www.soinside.com 2019 - 2024. All rights reserved.