Общая глобальная переменная в статической библиотеке C ++ - PullRequest
5 голосов
/ 06 июля 2010

У меня есть проект MS C ++ (назовем его проектом A), который я сейчас собираю как статическую библиотеку (.lib). Он определяет глобальную переменную foo. У меня есть два других проекта, которые компилируются отдельно (назовите их B и C, соответственно), и каждый связывает общую статическую библиотеку A в. Оба B и C являются DLL, которые в конечном итоге загружаются в одном и том же процессе. Я хотел бы поделиться одним экземпляром foo из A между B и C в одном и том же процессе: singleton. Я не уверен, как выполнить шаблон синглтона здесь с проектом A, так как он статически компилируется в B и C отдельно. Если я объявлю foo как extern как в B, так и в C, я получу разные экземпляры в B и C. Использование стандартного простого шаблона синглтона с статическим методом getInstance приводит к двум статическим экземплярам foo.

Есть ли способ сделать это, пока проект A статически компилируется в B и C? Или я должен сделать A DLL?

Ответы [ 3 ]

4 голосов
/ 06 июля 2010

Да, вы должны сделать A общей DLL или определить ее как extern в B и C и связать все три статически.

2 голосов
/ 06 июля 2010

Нет - они не являются общими.

Из «Windows через C / C ++» Рихтера (p583):

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

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

0 голосов
/ 01 ноября 2016

Я действительно получил эту проблему:

У меня есть A.EXE, связанный с B.LIB.У меня C.DLL также связан с B.LIB.

Как вы можете видеть, эти две программы связаны с B.LIB

Теперь, когда требуется, A.exe переходит на загрузку C.DLL.После загрузки A.EXE и C.DLL разделили B.LIB для кода и данных

Проблема в том, что можно связать "fantom" B.LIB с C.DLL для использования уже загруженногов A.exe?

думаю нет.Это ограничение из окна.В линуксе можно, если я правильно помню.Это было рассмотрено опцией -fPic GCC.Но не уверен.

Решением для обмена глобальными / статическими данными, хранящимися в B.LIB, с A.EXE и C.DLL является использование общего класса / интерфейсов.Интерфейс A.EXE для отправки в C.DLL с указателем данных / интерфейса на B.LIB, хранящийся в A.EXE.

Другими словами, если вашему C.DLL необходимо установить / совместно использовать состояниестатическая переменная в B.LIB, ваш A.EXE должен инициализировать C.DLL с интерфейсом, чтобы разрешить обмен данными с B.LIB в A.EXE.

В любом случае, B.LIB, хранящийся в C.DLL, продолжает раздувать глобальную программу из-за дублирования кода из B.LIB в A.EXE и C.DLL

.глобальное вздутие живота, вы должны разделить свою A.LIB на большее количество D.DLL, E.DLL, которые загружаются A.EXE и переданы через интерфейс в ваш C.DLL

. Чтобы уменьшить раздутый код до нуля,Вы должны использовать полностью независимый метод интерфейса.

...