2 / 2 / 0
Регистрация: 08.01.2016
Сообщений: 486
|
|||||||||||
1 | |||||||||||
Создание глобальной переменной в динамической библиотеке04.12.2021, 07:13. Показов 2264. Ответов 15
Доброе утро,
В своей динамической библиотеке мне необходимо хранить значение переменной (у которой тип определен в сторонней библиотеке) и по запросу передавать это значение в другие библиотеки (то есть моя библиотека будет зависимостью нескольких библиотек при работе моего приложения), при чем всем библиотекам должно приходить одно и то же значение. Также сторонние библиотеки должны иметь возможность задавать значение этой переменной (например через set функции) Поискал в интернете, не до конца понял, вроде мне необходимо сделать следующее: my.h
relocation R_X86_64_PC32 against undefined symbol `_ZN5h5geo2sr12_GLOBAL__N_116SpatialReferenceE' can not be used when making a shared object; recompile with -fPIC Правильно ли я понимаю что сторонняя библиотека, где определен тип OGRSpatialReference (GDAL библиотека) скомпилирована как статическая?
0
|
04.12.2021, 07:13 | |
Ответы с готовыми решениями:
15
Ошибка при обращении к динамической глобальной переменной Создание класса в динамической библиотеке Создание глобальной переменной по ходу работы программы Создание глобальной переменной Создание глобальной переменной |
фрилансер
5498 / 5094 / 1047
Регистрация: 11.10.2019
Сообщений: 13,338
|
||||||
04.12.2021, 07:38 | 2 | |||||
Kerim_Geophysic, определения переменной то нету
my.cpp
1
|
2 / 2 / 0
Регистрация: 08.01.2016
Сообщений: 486
|
||||||||||||||||
04.12.2021, 16:36 [ТС] | 3 | |||||||||||||||
Спасибо, не заметил
На самом деле у меня как-то странно работает эта глобальная переменная. То есть какие то функции работают, а какие то нет. У меня также определены несколько других функций:
При этом если я запускаю тест этой библиотеки, где я проделываю все тоже самое, все работает нормально (а в приложении как было сказано выбрасывает исключение). В чем может быть причина такого поведения?
0
|
фрилансер
5498 / 5094 / 1047
Регистрация: 11.10.2019
Сообщений: 13,338
|
|
04.12.2021, 17:01 | 4 |
почему туда передаётся нулевой указатель? Что в этой функции делается ?
1
|
2 / 2 / 0
Регистрация: 08.01.2016
Сообщений: 486
|
|
04.12.2021, 17:25 [ТС] | 5 |
Алексей1153,
по ссылке описание этой функции
Я это так понимаю: pszTargetKey используется для ускорения поиска AuthorityName, и если не знаешь какой pszTargetKey использовать, то используешь nullptr (в гугл тестах пробовал работает). Детально я описать не могу что происходит внутри этой функции, но в целом работа с данным классом происходит примерно так: есть база данных с описанием пространственных координатных систем (их названия, размеры эллипсоида, и другие параметры необходимые для математического описания каждой координатной системы). Когда я создаю объект типа OGRSpatialReference и выставляю необходимую координатную систему (в данном случае с помощью функции SetFromUserInput) то библиотека делает запрос в базу данных и если такая координатная система существует то функция SetFromUserInput возвращает какое то значение типа INT (грубо говоря если все нормально то 0, если ошибка то -1 например). Затем я могу выставить единицы измерения длины (футы/метры и тд). С помощью других классов я уже могу производить пересчет координат из одной системы в другую на основании этих объектов OGRSpatialReference . Кстати в этом же файле написано что при создании экземпляра этого класса используется счетчик ссылок на объект И здесь тоже описание есть
0
|
6105 / 3460 / 1405
Регистрация: 07.02.2019
Сообщений: 8,791
|
|
04.12.2021, 18:04 | 6 |
Kerim_Geophysic, этот метод может вернуть nullptr (что в вашем случае происходит). Вы не можете передавать в конструктор std::string nullptr. Проверяйте результат и, если он nullptr, возвращайте дефолтную строку.
1
|
2 / 2 / 0
Регистрация: 08.01.2016
Сообщений: 486
|
|||||||||||||||||||||
04.12.2021, 18:41 [ТС] | 7 | ||||||||||||||||||||
zayats80888, спасибо за ответ,
Я понимаю что этот метод может вернуть nullptr. Проблема в том что, если бы эта переменная была бы локальной то она бы не вернула nullptr, а вернула бы какое-то ненулевое значение. Представьте я работаю с координатной системой OGRSpatialReference SpatialReference. Я могу определить координатную систему с помощью AuthorityName и Code например так:
НО с юнитами все работает нормально в обоих случаях:
0
|
фрилансер
5498 / 5094 / 1047
Регистрация: 11.10.2019
Сообщений: 13,338
|
||||||
04.12.2021, 19:11 | 8 | |||||
Kerim_Geophysic, тут не нужно гадать. Правильно будет примерно так:
1
|
6105 / 3460 / 1405
Регистрация: 07.02.2019
Сообщений: 8,791
|
|
04.12.2021, 19:27 | 9 |
Трудно понять, что там у вас. Взять хотя бы объявление этого объекта: зачем оно сделано, если этот объект не экспортируется? Где находятся ваши функции и откуда вызываются. Поясните вкратце архитектуру вашего приложения.
1
|
2 / 2 / 0
Регистрация: 08.01.2016
Сообщений: 486
|
||||||
04.12.2021, 20:01 [ТС] | 10 | |||||
Алексей1153,
это я исправлю, спасибо
zayats80888, это Qt десктопное приложение. Объявлять или не объявлять переменную через extern я не знаю надо ли. Цель просто хранить значение SpatialReference так чтобы при вызове сеттеров/геттеров SpatialReference устанавливался/выдавал одинаковые значения для всех функций всех загруженных библиотек/приложения которые вызывают эти сеттеры/геттеры. Само приложение это Qt десктопное приложение. Построено на множестве динамических библиотек. Юзер через графический интерфейс выбирает authName и code которые через одну динамическую библиотеку устанавливают соответствующие значения в SpatialReference и для проверки я пытаюсь сразу вывести эти значения:
0
|
6105 / 3460 / 1405
Регистрация: 07.02.2019
Сообщений: 8,791
|
|
04.12.2021, 20:17 | 11 |
Если никто не обращается к этому объекту напрямую, а только через экспортируемый интерфейс библиотеки, то это объявление не нужно, иначе нужно его дополнить атрибутом экспорта/импорта.
В первом случае в cpp файле с определениями функций этой библиотеки просто определите глобальный объект в анонимном неймспэйсе. Вы для начала напишите простое консольное тестовое приложение, линкуйтесь только с этой библиоткой и проверяйте её функционал.
1
|
2 / 2 / 0
Регистрация: 08.01.2016
Сообщений: 486
|
|
04.12.2021, 22:44 [ТС] | 12 |
Сделал так сейчас, все работает если я линкуюсь к этой библиотеке и ее зависимостям. Пока не пойму что не так
0
|
6105 / 3460 / 1405
Регистрация: 07.02.2019
Сообщений: 8,791
|
|
04.12.2021, 23:01 | 13 |
Пройдитесь отладчиком. Убедитесь что UI работает корректно и что передаёте правильные параметры в функции. Большинство функций(SetFromUserInput в частности) возвращают коды ошибок, но вы это игнорируете.
Добавлено через 3 минуты А с библиотекой, а которой OGRSpatialReference, все ваши "модули" линкуются динамически? И нет ли конкурентных(из разных потоков) вызовов функций вашей библиотеки?
1
|
2 / 2 / 0
Регистрация: 08.01.2016
Сообщений: 486
|
|
04.12.2021, 23:23 [ТС] | 14 |
zayats80888, по моему важная деталь вскрылась...
упрощенная схема приложения: экзекютабл состоит только из main.cxx (назовем exe) основная динамическая библиотека, содержащая mainwindow.cxx в том числе (назовем exelib) модуль (динамическая библиотека) зависящий от exelib (назовем его module) +еще различные загружаемые модули, но они не должны играть роли в данном контексте. Раньше я пытался установить/вернуть значения authName и code внутри загружаемого модуля module. А только что я попытался сделать то же самое внутри MainWindow (то есть внутри основного модуля) и все прекрасно работает. Дальше не выключая приложения я "нажимаю кнопки" чтобы приложение по старому вывело те же самые значения но из модуля module и как обычно он выводит пустоту (или выбрасывает исключение как было до исправлений в коде, что не меняет сути). Может ли быть такое, что играет роль порядок загрузки модулей? Или может я не подключаю к модулю какую-то зависимость? Модуль компилируется отдельно и exelib линкуется к нему (exelib это зависимость модуля module). Добавлено через 5 минут По моему я как раз в этом накосячил... сейчас попробую
0
|
6105 / 3460 / 1405
Регистрация: 07.02.2019
Сообщений: 8,791
|
|
05.12.2021, 00:23 | 15 |
Не особо понял.
Есть matlab.dll (экспортирует класс OGRSpatialReference),Есть exelib.dll (вот эта библилотека), линкуется с(зависит от) matlab.dll .Есть module.dll , линкуется с(зависит от) matlab.dll и exelib.dll .Есть exe , линкуется с(зависит от) matlab.dll , exelib.dll и module.dll .Правильно? Далее, если вызывать функции exelib.dll из exe , то всё норм, а если опосредованно через module.dll , то не норм?Вроде нет, если dll уже загружена в процесс, она не будет "перезагружаться". Или вы в рантайме что-ли сами загружаете/выгружаете?
1
|
2 / 2 / 0
Регистрация: 08.01.2016
Сообщений: 486
|
|
05.12.2021, 01:29 [ТС] | 16 |
zayats80888,
Ранее я неправильно/неполно изложил структуру (извиняюсь). Еще раз попробую:
Есть matlab.dll (экспортирует класс OSGReference).Есть mylib.dll , линкуется с matlab.dll (экспортирует глобальную переменную OGRSpatialReference SpatialReference и сеттеры/геттеры которые мы обсуждали ранее).Есть exelib.dll (вот эта библиотека где все работает), линкуется с mylib.dll и следовательно с matlab.dll .Есть module.dll (здесь встречается указанная проблема), линкуется с mylib.dll и следовательно с matlab.dll (модуль встраиваемый, то есть приложение и без него сможет работать).Есть exe , линкуется только с exelib.dll Все это дело контролируется через СМАКЕ Кстати для общего понимания я на Ubuntu 20.04 сейчас Модули загружаются автоматически при запуске приложения, но вроде можно на программном уровне ставить зависимости одного модуля от другого (то есть у каждого модуля есть метод QStringList Dependencies() , то есть возвращает зависимости этого модуля, и может быть это используется при их загрузке). Мое приложение базируется на платформе Slicer 3DДобавлено через 57 минут zayats80888, кстати для работы matlab.dll необходима переменная окружения PROJ_LIB указывающая на папку где лежит база данных sqlite с координатными системами.Эта переменная устанавливается при запуске приложения, но возможно загружаемый модель ее игнорирует?
0
|
05.12.2021, 01:29 | |
05.12.2021, 01:29 | |
Помогаю со студенческими работами здесь
16
Создание глобальной переменной Создание глобальной переменной Создание массива в качестве глобальной переменной (по аналогии с VB.net) Различие глобальной и глобальной статической переменной Создание динамической переменной в android Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |