Получение указателей на функции из определенных файлов - PullRequest
0 голосов
/ 15 августа 2011

У меня есть много (возможно, сотни) различных файлов C ++.Каждая из них содержит 10 функций, каждая из которых принимает int и double и возвращает int.

Таким образом, указатель на одну из этих функций в одном из этих файлов будет выглядеть следующим образом:

int (*foo)(int, double);

И затем у меня есть класс, который содержит 10 из этих указателей на функции.

Возможно ли, чтобы конструктор этого класса взял имя файла одного из этих файлов c ++, поместил этот файл вфункции в свои указатели, и смогут ли использовать функции позже?

Желательно, чтобы это работало так, что даже если бы две функции из разных файлов имели одно и то же имя, оно все равно работало (идея состоит в том, что несколько программистов могли представитьразные файлы в списке, и они могут использовать одни и те же имена для своих 10 функций), но если это невозможно, я могу придумать что-нибудь, чтобы этого избежать.

Из того, что я искал, я не могуКажется, что-то находит, что позволяет вам различать файлы при выборе функций, и даже если бы я должен был объединить функциив одном файле все еще остается проблема определения 10 функций (поскольку все они имеют одинаковые аргументы).

Есть ли способ сделать это?Есть ли лучшее решение, о котором я просто не думаю?

Ответы [ 3 ]

1 голос
/ 15 августа 2011

Есть ли способ сделать это? Есть ли лучшее решение, которое я просто не думаешь?

Вы могли бы просто использовать для них разные пространства имен? Я имею в виду каждую группу из 10 функций в своем собственном пространстве имен; таким образом, они больше не будут конфликтовать.

Кроме этого, вы можете попробовать некоторые странности dlsym + dlopen (или их аналоги из win32). Это не то, что я бы сделал, хотя.

0 голосов
/ 15 августа 2011

Чтобы буквально выполнить то, что вы просите, вы можете превратить каждый файл C ++ в динамическую библиотеку и в конструкторе библиотеки зарегистрировать набор функций в некоторой глобальной карте, используя строку FILE в качестве ключа, или объявить их статическими. и убедитесь, что в каждом файле есть некоторая статическая переменная, инициализатор которой запускает регистрацию функций в той же глобальной карте.

Чтобы реализовать тот же подход с использованием плагинов, вы можете сделать это так, как я это сделал здесь (просто скачайте plugin.tgz, статья еще не готова). Содержание:

  • app.cc - приложение, загружающее все библиотеки плагинов
  • module.cc - класс плагина, реализующий бизнес-интерфейс module_ifc.h и «загружаемый» интерфейс bootstrap_ifc.h
  • client.cc - плагин, реализующий bootstrap_ifc.h и использующий метод из module.cc разрешается во время выполнения

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

Простой класс для работы с общими библиотеками в Linux:

#include <dlfcn.h>

class library {
  void* _handle;
public:
  library(char const* path);
  ~library();

  template <typename F> F func(char const* name);
};

library::library(char const* path) {
  _handle = dlopen(path, RTLD_NOW);
  if (!_handle) throw std::runtime_error(dlerror());
  std::clog << "opened library " << path << ", handle=" << std::hex << _handle << std::dec << "\n";
}

library::~library() {
  if (_handle) dlclose(_handle);
  std::clog << "closed library, handle=" << std::hex << _handle << std::dec << "\n";
}

template <typename F> F library::func(char const* name) {
  dlerror();
  F func = reinterpret_cast<F>(dlsym(_handle, name));
  const char *dlsym_error = dlerror();
  if (dlsym_error) throw std::runtime_error(dlsym_error);
  std::clog << "loaded symbol " << name << ", ptr=" << std::hex << ((void*)func) << std::dec << "\n";
  return func;
}
0 голосов
/ 15 августа 2011

Я полагаю, что вы описываете динамически подключаемую библиотеку (или общий объект в Linux-стране).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...