Форум программистов, компьютерный форум, киберфорум
Наши страницы
С++ для начинающих
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.83/6: Рейтинг темы: голосов - 6, средняя оценка - 4.83
Kapitan79
3 / 3 / 0
Регистрация: 13.10.2013
Сообщений: 157
1

Передача аргументов в функцию динамической библиотеки

09.12.2014, 10:57. Просмотров 1102. Ответов 19
Метки нет (Все метки)

И снова здравствуйте.

Я пытаюсь написать универсальный класс, который позволит мне обращаться к любым функциям динамических билиотек.
Проблема в том, что разные функции имеют разный набор аргументов разных типов. Соответственно не очень понятно какой тип переменной мне выбрать для передачи аргументов функции динамической библиотеки.

Самое умное что мне пришло в голову - использовать vector<void> и передавать указатели на переменные. Но этот вектор почемуто закопризничал и отказался выполнять resize и push_back.



Собственно текущий код класса

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#ifndef LIB_EXEC_H
#define LIB_EXEC_H
 
#include <stdio.h>
#include <iostream>
#include <vector>
 
using namespace std;
 
class lib_exec
{
public:
    lib_exec();
    void lib_func_exec();
    //vector<vector<std::string> >  result;
    void *result;
    vector <void> *argument;
    char *lib;
    char *method;
};
 
#endif // LIB_EXEC_H
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
#include "lib_exec.h"
 
lib_exec::lib_exec()
{
}
 
void lib_func_exec()
{
  void  *dl_handle      ;
  float (*func)(vector<void>)  ;
  char  *error          ;
 
  cout << "Открываем совместно используемую библиотеку" << endl;
  /* Открываем совместно используемую библиотеку */
  dl_handle = dlopen( lib, RTLD_LAZY )  ;
  if (!dl_handle)
  {
    printf( "!!! %s\n", dlerror() )     ;
    return                              ;
  }
 
  cout << "Находим адрес функции в библиотеке " << endl;
  /* Находим адрес функции в библиотеке */
  func  = dlsym( dl_handle, method );
  error = dlerror()                 ;
  if (error != NULL)
  {
    printf( "!!! %s\n", error )     ;
    return                          ;
  }
 
  cout << "Вызываем функцию по найденному адресу и печатаем результат" << endl;
  /* Вызываем функцию по найденному адресу и печатаем результат */
  result = *func(argument)  ;
 
  cout << "Закрываем объект" << endl;
  /* Закрываем объект */
  dlclose( dl_handle )      ;
 
}
Собственно вопросы:

1. Почему вектор отказывается изменять свой размер, ведь длина указателя по идее фиксированная и проблем быть не должно.
2. Какие ещё могут быть варианты "универсальной" переменной для передачи аргументов функции?
0
Лучшие ответы (1)
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
09.12.2014, 10:57
Ответы с готовыми решениями:

Вызов функции одной динамической библиотеки из другой динамической библиотеки
Добрый день! Помогите пожалуйста разобраться со следующим вопросом. ...

Передача аргументов в функцию
Привет! Пишу одну программку , и , собственно , уже написал , но код у меня в...

Передача аргументов в функцию
Доброго всем дня! Я немного не понял листинг программы из учебника Р.Лафоре: ...

Передача аргументов в функцию
При сборке кода выдает ошибку (её я написал в комментарий). Что значит ошибка?...

Передача аргументов в функцию
Хочу размерность массива задать в отдельной функции, но не получается...

19
nmcf
6515 / 5744 / 2617
Регистрация: 14.04.2014
Сообщений: 24,494
09.12.2014, 12:43 2
17-я строка сомнительна. Что за vector<void>?
Классы в библиотеку лучше не передавать, только простые типы и структуры.
0
Kapitan79
3 / 3 / 0
Регистрация: 13.10.2013
Сообщений: 157
09.12.2014, 13:17  [ТС] 3
Не в том идея.

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

Не хочется плодить одинаковые обращения к библиотеке.
0
nmcf
6515 / 5744 / 2617
Регистрация: 14.04.2014
Сообщений: 24,494
09.12.2014, 17:56 4
Передавай указатель и какой-нибудь идентификатор.
0
Kapitan79
3 / 3 / 0
Регистрация: 13.10.2013
Сообщений: 157
09.12.2014, 18:08  [ТС] 5
Я так и хочу поступить.
Но перечень параметров разных функций в разных библиотеках может быть очень разным по длине.
Соответственно, если я хочу сделать "универсальный" вызов для любой функции, перечень указателей на параметры должен в идеале храниться в массиве. Я решил использовать для этой цели вектор. Но с типом данных void он почемуто отказывается работать корректно.
0
nmcf
6515 / 5744 / 2617
Регистрация: 14.04.2014
Сообщений: 24,494
09.12.2014, 21:29 6
Почему нельзя реализовать несколько функций и уже при вызове решать какая подходит?
0
Kapitan79
3 / 3 / 0
Регистрация: 13.10.2013
Сообщений: 157
09.12.2014, 22:00  [ТС] 7
Можно... Просто не хочется)
Я надеюсь сделать одну универсальную функцию и больше эти вопросом не морочиться.
С С++ я недавно вожусь, а в PHP всегда так делал.
Если нет технической возможности, тогда разговор другой... Придётся делать несколько.
0
nmcf
6515 / 5744 / 2617
Регистрация: 14.04.2014
Сообщений: 24,494
09.12.2014, 23:21 8
Ну есть функции с переменным числом параметров, там многоточие ставится. Не знаю, будут ли работать в dll, но даже если будут всё равно придётся как-то передавать тип и там его приводить.
1
Kapitan79
3 / 3 / 0
Регистрация: 13.10.2013
Сообщений: 157
09.12.2014, 23:35  [ТС] 9
Не... Ни разу ни так...

Во прервых я под линух пишу)
Во вторых библиотеки я свои для себя делаю. Так что с той стороны будут мои значения разбираться и преобразовываться как я захочу. Это всё не вопрос...
А что за функции с многоточиями? Есть какоето научное у них название?
0
DrOffset
9014 / 4861 / 1196
Регистрация: 30.01.2014
Сообщений: 7,942
09.12.2014, 23:49 10
Цитата Сообщение от Kapitan79 Посмотреть сообщение
Есть какоето научное у них название?
Эллипсис.

PS. Не стоит в лоб тащить привычки из PHP в С++. Это языки с разными взглядами на типизацию.
1
Kapitan79
3 / 3 / 0
Регистрация: 13.10.2013
Сообщений: 157
10.12.2014, 00:00  [ТС] 11
Цитата Сообщение от DrOffset Посмотреть сообщение
Не стоит в лоб тащить привычки из PHP в С++
Сложно не согласиться. У меня просто пока не достаточно опыта чтобы сходу сказать что хорошо а что плохо.
Цитата Сообщение от DrOffset Посмотреть сообщение
Эллипсис
Спасибо! Интересная штука. Попробую применить...
0
DrOffset
9014 / 4861 / 1196
Регистрация: 30.01.2014
Сообщений: 7,942
10.12.2014, 18:01 12
Цитата Сообщение от Kapitan79 Посмотреть сообщение
Попробую применить...
Не думаю, что оно того стоит.
0
Kapitan79
3 / 3 / 0
Регистрация: 13.10.2013
Сообщений: 157
10.12.2014, 18:32  [ТС] 13
Цитата Сообщение от DrOffset Посмотреть сообщение
Не думаю, что оно того стоит.
Я тут подумал и решил что лучше параметры функции буду в виде текстовой строки передавать. Просто в установленном формате. В библиотеке будет стандартная функция которая будет эту строку разбирать и запускать нужную функцию.
Я понимаю, что для опытного человека возможно это выглядит не целесообразным, но попытка не пытка.
Просто код очень сильно облегчается, если обращение к любой функции любой написанной мной динамической библиотеки будет осуществляться в одном коротком формате. Тем более если обращение это многократное.
0
nmcf
6515 / 5744 / 2617
Регистрация: 14.04.2014
Сообщений: 24,494
10.12.2014, 20:02 14
Может тебе оставаться на PHP, если там задача лучше реализуется?
0
Kapitan79
3 / 3 / 0
Регистрация: 13.10.2013
Сообщений: 157
10.12.2014, 20:07  [ТС] 15
Не получится.
Да и не хочу.
В чём я не прав? Почему все с таким скепсисом относятся к такому стилю программирования?
Как будет оптимально писать, если я не прав?
0
nmcf
6515 / 5744 / 2617
Регистрация: 14.04.2014
Сообщений: 24,494
10.12.2014, 20:29 16
В С++ типы чётко различаются, здесь нет универсальных переменных как в некоторых других языках. Вот в рамках этого и надо программировать. Ну про многоточие уже писали, только такой вариант. А твою идею про строки я не понял.
0
DrOffset
9014 / 4861 / 1196
Регистрация: 30.01.2014
Сообщений: 7,942
10.12.2014, 20:50 17
Цитата Сообщение от Kapitan79 Посмотреть сообщение
В чём я не прав? Почему все с таким скепсисом относятся к такому стилю программирования?
Потому что языки с динамичекой типизацией для того и придумали, чтобы решать подобные твоей проблемы проще.
С++ - язык со статической типизацией. Т.е. весь код пляшет от типа.
Скепсис потому, что на С++ далеко от типа не убежишь и написать "универсальную функцию на все случаи жизни" все равно не выйдет, все равно где-то придется возвращаться к типизации. В рамках какого-либо частного случая можно конечно решить твою проблему. По крайне мере это будет просто на стороне использования. Обычно большего и не надо. Выше уже предлагали, передавать указатель void * и id. Реально будет только один вызов, но в рамках допустимых типов (которые мы сами предусмотрели). Можно возложить контроль за правильностью такой передачи на компилятор с помощью простого шаблона. Тогда со стороны использования не будет видно, что там что-то еще передается.

Но, опять же, если задача стоит написать универсальный библиотечный вызов - это неправильная задача. Сначала нужно задать себе вопрос о том, что мы этим добъемся? Какую реальную проблему решим?
Озвучь задачу, которую ты хотел решить с помощью этой универсальной функции, и тебе подскажут правильное решение.

PS. Вот была уже подобная тема. Но там что-то втолковать человеку так и не вышло.

Писать на С++ надо как на С++, не как на PHP. Вот и все, Те вещи, которые в PHP делаются так, в С++ делаются эдак. Родство синтаксиса не должно вводить в заблуждение, что код можно переносить 1 в 1. Каждому инструменту нужна своя сноровка.

Добавлено через 7 минут
Kapitan79, Да, если нужен безопасный сторадж для различных типов, то можно посмотреть на boost::any.
Хотя число задач, где он реально нужен и без него никак, практически стремится к нулю.
0
Kapitan79
3 / 3 / 0
Регистрация: 13.10.2013
Сообщений: 157
10.12.2014, 21:21  [ТС] 18
Задачи написать универсальный библиотечный вызов не стоит. Более того, я не могу пока точно утверждать, что мне нужна динамическая библиотека, хотя по всему так и выходит.
Если в двух словах - задача следующая.

Имеются 3 демона (написанные на С++), которые в случае возникновения определённый значений в базе данных меняют другие значения по заданным правилам (демоны проверяют значения раз в заданный период времени). Смысл изменений значений в базе данных для каждого демона разный.

Кроме того возможен вариант, при котором на устройстве, на котором будут работать демоны, базы данных не будет в силу малых ресурсов. В этом случае в качестве источника данных будут использоваться структурированные файлы. Может быть файлы JSON...

Главная задача состоит в том, что нужно написать редактор с WEB интерфейсом, который позволял создавать вышеуказанные правила.

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

Примерно так, хотя это пока не до конца продуманный набросок.

До этого я уже сделал вариант этих правил в формате JSON на PHP, но такой вариант был забракован из за жёсткости формата правила (они строились на тандартном шаблоне набор условий -> набор действий при их выполнении).

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

В результате решено всё делать на с++.
0
DrOffset
9014 / 4861 / 1196
Регистрация: 30.01.2014
Сообщений: 7,942
10.12.2014, 21:43 19
Лучший ответ Сообщение было отмечено Kapitan79 как решение

Решение

Kapitan79, конечно вариант писать плагин на С++, а потом на лету его компилировать в so имеет право на жизнь. Просто нужно заранее спроектировать интерфейс вызова этих so-модулей демонами. Это и будет отправная точка. Каждый раз, когда мы пишем новый "скрипт", будет создаваться новая реализация для эти интерфейсов, которая будет делать конкретную работу, а демоны всегда будут работать с абстрактным классом. Идея в том, что демоны не должны знать конкретику, они работаю с общим абстрактным интерфейсом, а реализация внутри модулей делают свою работу.
Советую поизучать как проектируются плагинные системы на примере реальных проектов (хорошие иллюстрации есть в документации к Qt).

Но лично я все-таки использовал бы здесь интегрированный скриптовый язык. Например lua. Его ниша как раз в тесном взаимодействии с С\С++ и скорость.
1
Kapitan79
3 / 3 / 0
Регистрация: 13.10.2013
Сообщений: 157
10.12.2014, 22:06  [ТС] 20
Цитата Сообщение от DrOffset Посмотреть сообщение
Например lua
Спасибо за совет. Обязательно посмотрю!
0
10.12.2014, 22:06
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
10.12.2014, 22:06

Передача аргументов в функцию
как передать аргумент в функцию по указателю? нашел только по значению: int...

Передача аргументов в функцию
Что сработает быстрее? void Func(const A &amp;a = A(0, 0, 0)) { } или ...

Передача аргументов в функцию
Прошу помощи в разборе багов кода. Ошибка при компиляции связана с неверной...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru