Есть указатель на функцию, расположенную в DLL библиотеке. Можно ли эту функцию сохранить в объекте типа std::function<...>
при корректном указании шаблонных параметров, затем отключить библиотеку через FreeLibrary
(работаю в MSVC) и работать с функцией через std::function
? Мне просто надо запихать туда разыменованный указатель на эту функцию?
Т.е., простыми словами, что вы хотите сделать (вернее, что у вас получится) - вы сохраняете указатель на функцию, выбрасываете из памяти код функции, оставляя указатель непонятно куда, и вызываете ее...
Как вы думаете, что у вас получится?
std::function
тело функции никоим образом не сохраняет. Ну, а указатель на функцию будет инвалидирован вызовом FreeLibrary
.
Набросать соответствующий код очень просто, можете убедиться сами...
indll.cpp
#include <iostream>
#include <iomanip>
using namespace std;
extern "C" void __declspec(dllexport) inDll()
{
cout << "From DLL\n";
}
Компилируем как cl /LD indll.cpp
test.cpp
#include <iostream>
#include <iomanip>
#include <functional>
#include <windows.h>
using namespace std;
int main(int argc, const char * argv[])
{
HMODULE dll;
if (0 != (dll = LoadLibrary("inDll.dll")))
{
cout << "Load success\n";
FARPROC ptr = GetProcAddress(dll,"inDll");
function<void(void)> f = ptr;
f();
FreeLibrary(dll);
}
}
Компилируем как cl test.cpp
Запускаем test.exe
, убеждаемся, что все работает. Меняем местами строки
f();
FreeLibrary(dll);
компилируем и убеждаемся окончательно, что так поступать нельзя :)
Ни в языке С, ни в языке С++ нет понятия "сохранить функцию". Любые манипуляции с std::function
или чем-то подобным будут работать только и именно с указателем на оригинальную функцию.
С "разыменованным указателем на функцию" в С++ можно сделать только весьма ограниченное количество вещей: например, вызвать функцию или преобразовать его обратно в указатель. "Запихать" результат разыменования никуда нельзя.
std::function
является лишь обёрткой над некоторой сущностью, которую можно вызвать. Если код этой сущности становится недоступен (например, после выполнения FreeLibrary
), то попытки вызвать его будут приводить к неопределённому поведению. Скорее всего Вы просто получите некоторую ошибку времени выполнения от операционной системы.
Не стоит считать std::function
каким-то волшебным контейнером, который хранит код, и если его куда-то передать, то он может быть выполнен. Иначе можно было бы развить мысль и предположить, что, скажем, упаковка и передача объекта std::function
по сети на другое устройство будет допускать возможность выполнить код, "хранимый" в этом объекте. Такое невозможно хотя бы по причине того, что на другом конце сети может быть устройство совершенно иной архитектуры и код (грубо говоря, последовательность команд) должен быть совсем иным. Для обеспечения подобного используются другие технологии, например, CORBA.
Кофе для программистов: как напиток влияет на продуктивность кодеров?
Рекламные вывески: как привлечь внимание и увеличить продажи
Стратегії та тренди в SMM - Технології, що формують майбутнє сьогодні
Выделенный сервер, что это, для чего нужен и какие характеристики важны?
У меня есть таблицаКласс Table, унаследованый от QTableWidget и есть база данных
Здравствуйте, возникла проблема при подключении полосы прокрутки к окнуВ общем в окне рисуется график, при этом координаты смещаются с помощью...
При компиляции под win64 все работает корректноПри компиляции под Android вылетает ошибка: