Я нахожусь в процессе написания своего рода системы / интерпретатора времени выполнения, и одна из вещей, которые мне нужно уметь делать, это вызывать функции c / c ++, расположенные во внешних библиотеках.
Вы, вероятно, можете проверить примеры того, как Tcl и Python делают это.Если вы знакомы с Perl, вы также можете проверить Perl XS .
Общий подход заключается в том, чтобы дополнительная библиотека шлюза располагалась между вашим интерпретатором и целевой библиотекой C.Исходя из моего опыта работы с Perl XS, основными причинами являются управление памятью / сборка мусора и типы данных C, которые трудно / невозможно отобразить непосредственно на язык интерпретатора.
Итак, я спрашиваю:, есть ли способ вызвать динамически загруженную функцию, передать ей аргументы и получить ее возвращаемое значение, не зная, что это прототип?
Мне неизвестно.
Гарантироватьвсе функции, которые я хочу загрузить, имеют один и тот же прототип и предоставляют некоторый механизм сортировки для этих функций для получения параметров и возвращаемых значений.Это то, что я делаю сейчас.
Это то, что в моем проекте делает и другая команда.У них есть стандартизированный API для внешних плагинов на что-то вроде этого:
typedef std::list< std::string > string_list_t;
string_list_t func1(string_list_t stdin, string_list_t &stderr);
Обычными задачами для плагинов является выполнение преобразования или сопоставления или расширения ввода, часто с использованием СУБД.
Предыдущие версии интерфейса со временем становились неосуществимыми, вызывая проблемы как у покупателей, так и у разработчиков продуктов и сторонних разработчиков плагинов.Легкомысленное использование std :: string допускается тем фактом, что плагины вызываются относительно редко (и все же накладные расходы по сравнению с SQL используются повсеместно).Аргумент stdin
заполняется вводом в зависимости от типа плагина.Вызов плагина считается неудачным, если внутри выходного параметра stderr
любая строка начинается с 'E:' (W: для предупреждений, остальные игнорируются, поэтому могут использоваться для разработки / отладки плагинов).
dlsym
используется только один раз для функции с предопределенным именем для выборки из массива совместно используемой библиотеки с таблицей функций (публичное имя функции, тип, указатель и т. Д.).