Выбор библиотеки для ссылки во время выполнения - PullRequest
1 голос
/ 27 января 2012

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

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

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

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

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

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

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

          bind(...)

вместо:

         udt_calls->bind(...)

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

1 Ответ

1 голос
/ 28 января 2012

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

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

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

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

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

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

#define bind udt_calls->bind
...