Я думаю, вам понадобится помощь из общей библиотеки, чтобы сделать это любым переносным способом. Он не обязательно должен знать что-либо об объектах, разделяемых между модулями, он просто должен обеспечить глобально доступное сопоставление от ключа (возможно, строки) до указателя.
Однако, если вы хотите вызывать API-интерфейсы ОС, это выполнимо, и я думаю, что вам могут понадобиться только две реализации специфичной для ОС части (одна для Windows DLL и GetProcAddress, другая для ОС, использующих dlopen).
Когда каждый модуль загружается, он просматривает список ранее загруженных модулей, ища те, которые экспортируют функцию с особым именем. Если он находит один (любой, не имеет значения, какой, поскольку инвариант состоит в том, что все полностью загруженные модули знают об общем объекте), он получает адрес общего объекта из ранее загруженного модуля, а затем увеличивает счетчик ссылок. , Если он не может их найти, он распределяет новые данные и инициализирует счетчик ссылок. Во время выгрузки модуля он уменьшает счетчик ссылок и освобождает общий объект, если счетчик ссылок достиг нуля.
Конечно, необходимо использовать распределитель ОС для общего объекта, потому что, хотя это маловероятно, возможно, что он освобожден из библиотеки, отличной от той, которая его первой загрузила. Это также подразумевает, что общий объект не может содержать какие-либо виртуальные функции или любые другие указатели на сегменты различных модулей. Все его ресурсы должны быть динамически распределены с использованием распределителя процесса всей ОС. Это, вероятно, меньше нагрузки на системы, где libc ++ является разделяемой библиотекой, но вы сказали, что статически связываете CRT.
Функции, необходимые в Win32, включают EnumProcessModules
, GetProcAddress
, HeapAlloc
и HeapFree
, GetProcessHeap
и GetCurrentProcess
.
Учитывая все вышесказанное, я думаю, что я бы придерживался того, чтобы поместить общий объект в его собственную разделяемую библиотеку, которая использует структуры данных загрузчика, чтобы найти его. В противном случае вы заново изобретаете загрузчик. Это будет работать, даже если CRT статически связан в несколько модулей, но я думаю, что вы настраиваете себя на нарушения ODR. Будьте особенно внимательны при хранении общих данных POD.