Добавить TargetPath без ведущих котировок [дубликат]

Это довольно известное различие между Windows и Unix-подобными системами.

Независимо от того, что:

  • Каждый процесс имеет свои собственные адресное пространство, означающее, что между процессами никогда не используется какая-либо память (если вы не используете некоторую межпроцессную библиотеку или расширения связи).
  • Правило One Definition (ODR) все еще сохраняется применяется, что означает, что вы можете иметь только одно определение глобальной переменной, видимое во время ссылки (статическое или динамическое связывание).

Итак, ключевая проблема здесь - действительно видимость .

Во всех случаях глобальные переменные (или функции) 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 ++, это платформа, гораздо менее надежна / переносима).

1
задан Ansgar Wiechers 12 May 2016 в 07:55
поделиться

1 ответ

Если вы сомневаетесь, прочитайте документацию .

Из свойства TargetPath - Примечания Раздел Это свойство предназначено для ярлыка целевой путь. Любые аргументы в ярлыке должны быть помещены в свойство Аргумент.

Аргументы команды принадлежат свойству Arguments :

Set oShellLink = objShell.CreateShortcut("shortcut.lnk")
oShellLink.TargetPath = "C:\Windows\System32\mshta.exe"
oShellLink.Arguments = "D:\path\to\file.hta"
...
oShellLink.Save
4
ответ дан Lankymart 18 August 2018 в 10:14
поделиться
  • 1
    Как я уже сказал, я никогда не чувствую себя в одиночестве, используя VBscript. – Rahul 12 May 2016 в 07:55
  • 2
    @ Scripting.FileSystemObject. Нет причин не читать документацию , спрашивая здесь, должно быть последнее средство. – Lankymart 12 May 2016 в 08:21
  • 3
    предлагаемая документация - это то же самое, что я использовал для примера, но прямо не объяснил, как oShellLink.Arguments очевидна. Я понятия не имею, как работает ориентация объектов. – Rahul 12 May 2016 в 08:31
  • 4
    @ Scripting.FileSystemObject И это не ? Любое значение, переданное в конце пути в UNIX, Windows и т. Д., Известно как аргумент (иногда параметр) . Моя точка зрения заключается в том, что не требуется много (просто немного копать) для тренировки, как следует указывать аргументы. – Lankymart 12 May 2016 в 09:11
  • 5
    @ Scripting.FileSystemObject Фактически страница свойств TargetPath говорит об этом в разделе «Примечания» - ». Это свойство предназначено только для целевого пути ярлыка. Любые аргументы для ярлыка должны быть помещены в свойство Аргумента . & quot; , довольно ясное для меня. – Lankymart 12 May 2016 в 09:15
Другие вопросы по тегам:

Похожие вопросы: