При условии, что в описанном проекте только заголовочные файлы в каталоге mylib/include
должны считаться общедоступными:
Верхний уровень CMakeLists.txt
для mylib
должен содержать:
[110 ]
Это гарантирует, что проекты, включающие mylib
, будут иметь доступ только к файлам в каталоге include/
. Файлы в include/
могут использоваться как #include
, а файлы в include/mylib
(общее соглашение) могут использоваться как #include
.
Верхний уровень CMakeLists.txt
для myapp
должен включать:
cmake_minimum_required(VERSION 3.13 FATAL_ERROR)
project(myapp VERSION 0.1 LANGUAGES CXX)
add_subdirectory(libs/mylib)
add_executable(${MyAppName} ${MyApp_SOURCES})
target_link_libraries(${MyAppName} ${MyLibName}
Использование add_subdirectory
гарантирует, что mylib
будет построено до myapp
, а target_link_libraries
добавляет [ 1117] к исполняемому файлу.
Как упоминал Цалумэн, обязательно посмотрите учебники по CMake и предпочитаете использовать cmake --build .
вместо make
.
Краткий ответ:
Да, как правило, можно вызывать функцию DLL из нескольких потоков, поскольку каждый поток имеет свой собственный стек, и вызов функции DLL более или менее аналогичен вызову любой другой функции из вашего собственного кода.
Длинный ответ:
Если это , то на самом деле возможно зависит от функций DLL использовать совместно изменяемое состояние или нет.
Например, если вы делаете что-то вроде этого:
DLL_SetUser(UserName, Password)
if DLL_IsAuthenticated then
begin
...
end;
Тогда, безусловно, не безопасно использовать из разных потоков. В этом примере вы не можете гарантировать, что между DLL_SetUser
и DLL_IsAuthenticated
ни один другой поток не сделает другой вызов DLL_SetUser
.
Но если функции DLL делают не зависит от какого-то заранее определенного состояния, т.е. все необходимые параметры доступны сразу, а все остальные конфигурации одинаковы для всех потоков, можно предположить, что это будет работать.
if DLL_IsAuthenticated(UserName, Password) then
begin
...
end;
Но будьте осторожны: возможно, функция DLL выглядит атомарно, но внутренне использует что-то, что нет. Например, если библиотека DLL создает временный файл с всегда одинаковым именем или обращается к базе данных, которая может обрабатывать только один запрос за раз, она считается общим состоянием. (Извините, я не мог придумать более хороших примеров)
Резюме:
Если бы поставщики DLL сказали, что их DLL являются поточно-ориентированными, я бы использовал их из нескольких потоков без блокировки. Если это не так - или даже если поставщики не знают - вы должны быть осторожны и использовать блокировку.
По крайней мере, пока у вас не возникнут проблемы с производительностью.
Чтобы ваши библиотеки DLL были поточно-ориентированными, вам необходимо защитить все общие структуры данных, к которым могут обращаться несколько потоков в одном процессе. одновременно - здесь нет никакой разницы между написанием кода для DLL и написанием кода для исполняемого файла.
Для нескольких процессов нет риска в параллельном доступе, поскольку каждый процесс получает свой собственный сегмент данных для DLL, поэтому переменные с одно и то же имя на самом деле отличается, если смотреть из разных процессов. На самом деле гораздо сложнее предоставить данные в DLL, которая одинакова для разных процессов, вам, в основном, потребуется реализовать те же вещи, которые вы использовали бы для обмена данными между процессами.
Обратите внимание, что DLL особенная в том смысле, что вы получать уведомления, когда процесс или поток присоединяется к DLL или отсоединяется от нее. См. Документацию для функции обратного вызова DllMain для объяснения, и этой статьи для примера, как использовать это в написанной на Delphi DLL. Поэтому, если ваши потоки не являются полностью независимыми друг от друга (и нет общих данных, к которым имеется доступ для записи), вам понадобятся некоторые общие структуры данных с синхронизированным доступом. Различные уведомления могут помочь вам с правильной настройкой любых структур данных в вашей DLL.
Если ваши DLL позволяют полностью независимое выполнение экспортируемых функций, также проверьте threadvar специфичные для потока переменные. Обратите внимание, что для них разделы инициализации и финализации непригодны для использования, но, возможно, уведомления о потоках также могут вам помочь.
и этой статье для примера, как использовать это в написанной на Delphi DLL. Поэтому, если ваши потоки не являются полностью независимыми друг от друга (и нет общих данных, к которым имеется доступ для записи), вам понадобятся некоторые общие структуры данных с синхронизированным доступом. Различные уведомления могут помочь вам с правильной настройкой любых структур данных в вашей DLL.Если ваши DLL позволяют полностью независимое выполнение экспортируемых функций, также проверьте threadvar специфичные для потока переменные. Обратите внимание, что для них разделы инициализации и финализации непригодны для использования, но, возможно, уведомления о потоках также могут вам помочь.
и этой статье для примера, как использовать это в написанной на Delphi DLL. Поэтому, если ваши потоки не являются полностью независимыми друг от друга (и нет общих данных, к которым имеется доступ для записи), вам понадобятся некоторые общие структуры данных с синхронизированным доступом. Различные уведомления могут помочь вам с правильной настройкой любых структур данных в вашей DLL.Если ваши DLL позволяют полностью независимое выполнение экспортируемых функций, также проверьте threadvar специфичные для потока переменные. Обратите внимание, что для них разделы инициализации и финализации непригодны для использования, но, возможно, уведомления о потоках также могут вам помочь.
тогда вам понадобятся некоторые общие структуры данных с синхронизированным доступом. Различные уведомления могут помочь вам с правильной настройкой любых структур данных в вашей DLL.Если ваши DLL позволяют полностью независимое выполнение экспортируемых функций, также проверьте threadvar специфичные для потока переменные. Обратите внимание, что для них разделы инициализации и финализации непригодны для использования, но, возможно, уведомления о потоках также могут вам помочь.
тогда вам понадобятся некоторые общие структуры данных с синхронизированным доступом. Различные уведомления могут помочь вам с правильной настройкой любых структур данных в вашей DLL.Если ваши DLL позволяют полностью независимое выполнение экспортируемых функций, также проверьте threadvar специфичные для потока переменные. Обратите внимание, что для них разделы инициализации и финализации непригодны для использования, но, возможно, уведомления о потоках также могут вам помочь.
Вот в чем дело - вы не можете предполагать, что библиотеки DLL являются поточно-ориентированными, если у вас нет контроля над исходным кодом (или документация, подтверждающая, что это так), поэтому следует предположить, что они худшие.
Если вы говорите о библиотеках Win32, они должны быть безопасными, если их вызывают несколько потоков, приложений. Я не знаю, что делает ваша DLL, но если ваша DLL использует блокируемый ресурс, такой как файл или порт, то могут возникнуть проблемы, связанные с реализацией внутри DLL.
Я не знаком с работой DLL-библиотеки аутентификации Delphi 2009 Возможно, вам следует добавить эту информацию в заголовок (о котором вы говорите конкретно о DLL-библиотеках Delphi 2009)