Это довольно известное различие между Windows и Unix-подобными системами.
Независимо от того, что:
Итак, ключевая проблема здесь - действительно видимость .
Во всех случаях глобальные переменные (или функции) static
никогда не видны извне модуля (dll / so или executable). Стандарт C ++ требует, чтобы у них была внутренняя связь, что означает, что они не видны за пределами единицы перевода (которая становится объектным файлом), в которой они определены. Итак, это решает эту проблему.
Там, где это усложняется, вы имеете extern
глобальные переменные. Здесь ОС и Unix-подобные системы совершенно разные.
В случае Windows (.exe и .dll) глобальные переменные extern
не являются частью экспортированных символов. Другими словами, разные модули никоим образом не знают глобальных переменных, определенных в других модулях. Это означает, что вы получите ошибки компоновщика, если попытаетесь, например, создать исполняемый файл, который должен использовать переменную extern
, определенную в DLL, потому что это недопустимо. Вам нужно будет предоставить объектный файл (или статическую библиотеку) с определением этой внешней переменной и связать его статически с как с исполняемым файлом, так и с DLL, в результате получится две различные глобальные переменные (одна из которых принадлежит исполняемый и один, принадлежащий к DLL).
Чтобы фактически экспортировать глобальную переменную в Windows, вы должны использовать синтаксис, аналогичный синтаксису экспорта / импорта функции, то есть:
#ifdef COMPILING_THE_DLL
#define MY_DLL_EXPORT extern "C" __declspec(dllexport)
#else
#define MY_DLL_EXPORT extern "C" __declspec(dllimport)
#endif
MY_DLL_EXPORT int my_global;
Когда вы это делаете, глобальная переменная добавляется в список экспортированных символов и может быть связана как и все другие функции.
В случае Unix-подобных сред (например, Linux) динамическая библиотеки, называемые «общие объекты» с расширением .so
экспортируют все extern
глобальные переменные (или функции). В этом случае, если вы выполняете время загрузки , связанное из любого места в общий файл объекта, тогда глобальные переменные являются совместно используемыми, т. Е. Связаны друг с другом как единое целое. В принципе, Unix-подобные системы разработаны таким образом, что практически нет никакой разницы между связыванием со статической или динамической библиотекой. Опять же, ODR применяется по всем направлениям: глобальная переменная extern
будет разделяться между модулями, а это означает, что у нее должно быть только одно определение для всех загруженных модулей.
Наконец, в обоих случаях для Windows или Unix-подобных системах вы можете выполнить время выполнения динамической библиотеки, то есть используя либо LoadLibrary()
/ GetProcAddress()
/ FreeLibrary()
, либо dlopen()
/ dlsym()
/ dlclose()
. В этом случае вам нужно вручную получить указатель на каждый из символов, которые вы хотите использовать, и который включает в себя глобальные переменные, которые вы хотите использовать. Для глобальных переменных вы можете использовать GetProcAddress()
или dlsym()
так же, как и для функций, при условии, что глобальные переменные являются частью списка экспортированных символов (по правилам предыдущих абзацев).
И, конечно же, в качестве необходимой окончательной заметки: следует избегать глобальных переменных. И я считаю, что текст, который вы цитировали (о том, что «неясно»), относится точно к различиям, специфичным для платформы, которые я только что объяснил (динамические библиотеки на самом деле не определены стандартом C ++, это платформа, гораздо менее надежна / переносима).
Если вы сомневаетесь, прочитайте документацию .
Из свойства TargetPath - Примечания Раздел Это свойство предназначено для ярлыка целевой путь. Любые аргументы в ярлыке должны быть помещены в свойство Аргумент.
blockquote>Аргументы команды принадлежат свойству
Arguments
:Set oShellLink = objShell.CreateShortcut("shortcut.lnk") oShellLink.TargetPath = "C:\Windows\System32\mshta.exe" oShellLink.Arguments = "D:\path\to\file.hta" ... oShellLink.Save
TargetPath
говорит об этом в разделе «Примечания» - ». Это свойство предназначено только для целевого пути ярлыка. Любые аргументы для ярлыка должны быть помещены в свойство Аргумента . & quot; i>, довольно ясное для меня. – Lankymart 12 May 2016 в 09:15