Выбор библиотеки для ссылки во время выполнения

Я пытаюсь изменить iperf для поддержки другого протокола (UDT). API UDT написан так, что он отражает стандартные вызовы BSD:

  socket(...);
  bind(...);
  listen(...);

Тогда мне нужно условно связать библиотеку UDT, чтобы эти вызовы в iperf использовали код UDT вместо интерфейса сокета со стеком TCP. Можно ли это сделать? Я всегда мог просто загрузить библиотеку и иметь другой условный путь, используя пространство имен UDT::, но было бы 1) много дублирования из пути TCP и 2) было бы много изменений там, где, возможно, не должно быть ни одного. Пожалуйста, дайте мне знать, если мне неясно, приветствуются любые предложения о том, как добиться этого динамического связывания.

Редактировать:

Используя семейство dlopen(), упомянутое ниже, у меня может быть следующий поток программ:

Разобрать параметры строки cmd -> если запрашивается UDT, загрузить библиотеку libudt -> get и сохранить дескрипторы для всех функций BSD UDT (bind, listen и т. Д.)

На данный момент у меня есть указатели функций, хранящиеся со всеми моими функциями UDT. Допустим, я храню их все в структуре с именем udt_calls. Теперь у меня есть проблема с существующим кодом, который просто делает такие вызовы:

          bind(...)

скорее, чем:

         udt_calls->bind(...)

Есть ли чистый способ, которым я могу глобально переопределить любой вызов BSD по всей программе с помощью моих теперь загруженных указателей на функции в моей структуре udt_calls?

1 ответ

Решение

Да, это можно сделать. Вам нужно использовать динамическую загрузку библиотеки. В Windows это делается с помощью LoadLibrary, В Linux или Unix это делается с помощью dlopen и друзья.

Вы захотите прочитать документацию и посмотреть примеры для этих функций. Вкратце, вы создаете несколько указателей на функции (часто это делается в структуре, а в Windows есть несколько хитростей, позволяющих загрузить их в класс виртуальных функций C++). Затем вы используете функции динамической загрузки, чтобы открыть библиотеку, а затем назначаете указатели на функции, чтобы они указывали на функции внутри библиотеки.

Затем вы выполняете вызовы функций, используя указатели функций (или виртуальные функции C++).

Редактировать: Похоже, есть способы использовать виртуальные базовые классы C++ в Unix.

Изменить: я считаю, что большинство систем заставляют библиотеки операционной системы использовать "слабые" символы. Это означает, что вы можете определить свои собственные глобальные символы с тем же именем и переопределить версию библиотеки ОС. Попробуйте объявить глобальные указатели функций в вашей собственной программе, чтобы обеспечить глобальные версии bind а также listen,

Другим вариантом может быть объявление ваших указателей в структуре, а затем использование препроцессора, например:

#define bind udt_calls->bind
Другие вопросы по тегам