В Ubuntu 14.04 у меня есть C++ API как разделяемая библиотека, которую я открываю с помощью dlopen
, а затем создаю указатели на функции с помощью dlsym
. Одна из этих функций CloseAPI
выпускает API из памяти. Вот синтаксис:
void* APIhandle = dlopen("Kinova.API.USBCommandLayerUbuntu.so", RTLD_NOW|RTLD_GLOBAL);
int (*CloseAPI) = (int (*)()) dlsym(APIhandle,"CloseAPI");
Если я гарантирую, что во время моего кода функция CloseAPI
всегда вызывается до возвращения main
функции, тогда все кажется прекрасным, и я могу снова запустить программу в следующий раз. Однако, если я Ctrl-C
и CloseAPI
программу, прежде чем он успел позвонить в CloseAPI
, то в следующий раз, когда я запустил программу, я получаю обратную ошибку всякий раз, когда я вызываю любую из функций API. У меня нет документации о том, что это за ошибка, но моя интуиция заключается в том, что в предыдущей программе была некоторая блокировка в библиотеке. Единственное, что позволяет мне снова запустить программу, - это перезагрузить мою машину. Вход и выход не работает.
Итак, мои вопросы:
1) Если моя библиотека является общей библиотекой, почему я получаю эту ошибку, если бы я думал, что общая библиотека может быть загружена более чем одной программой одновременно?
2) Как я могу решить эту проблему, если я буду ожидать, что Ctrl-C
будет происходить часто, не имея возможности вызвать CloseAPI
?
Итак, если вы правильно используете этот api, тогда вам нужно выполнить правильную очистку после использования (что не очень удобно).
Прежде всего, если вам действительно нужно использовать Ctrl-C, позвольте программе правильно закончить этот сигнал: вызван ли деструктор, если вышли SIGINT или SIGSTP?
Затем используйте технику с объектом стека, содержащим указатель ресурса (в этом случае функции CloseAPI). Затем убедитесь, что этот объект вызовет CloseAPI в своем деструкторе (вы можете проверить, не был ли ранее закрыт CloseAPI). Подробнее см. В разделе "Эффективный C++, глава 3: Управление ресурсами".
Чтобы он, даже если вы не вызываете CloseAPI, контейнер указателей сделает это за вас.
ps, вы должны подумать об этом, даже если вы не собираетесь использовать Ctrl-C. Представьте, что произошло исключение, и ваша программа должна быть остановлена: тогда вы должны быть уверены, что не оставите OS в неопределенном состоянии.
signal(2)
илиsigaction(2)
и вызовCloseAPI
в обработчике были быCloseAPI
вариантом.