Стандарт C написан так, чтобы предполагать, что указатели на разные типы объектов, и особенно указатели на функции, в отличие от типов объектов, могут иметь разные представления. Вот почему, как правило, вы не хотите смешивать указатели, иначе современный компилятор предупредит вас, и если вы хотите отключить предупреждения, вы обычно используете явное приведение.
dlsym
, с другой стороны, самим своим существованием предполагает, что все указатели в значительной степени одинаковы, потому что он должен иметь возможность возвращать вам любой указатель на любой тип данных - объект или функцию - в ваш объектный файл.
Другими словами, код, использующий dlsym
, по своей природе непереносим, в том смысле, что он не является широко переносимым, в том смысле, что он переносится «только» на те машины, на которых все указатели безопасно взаимно конвертируемы. (Это, конечно, практически все популярные сегодня машины.)
Итак, да, вам нужно будет привести указатели, чтобы заглушить предупреждения, и при этом вы можете сделать свой код менее переносимым на машины, где все указатели не одинаковы (и где предупреждения, если они не заглушены, будут правильно сообщаю вам, что ваш код не будет работать), но dlsym
в любом случае никогда не будет работать (или даже существовать в его текущей форме) на этих машинах.
(И если gcc -pedantic
предупреждает вас даже о явном преобразовании void *
в тип указателя функции, вы ничего не можете сделать, кроме как переключиться на другую версию gcc
или, конечно, не использовать -pedantic
.)
Дополнение: мой ответ звучал так, будто преобразование указателей на разные типы данных может быть проблемой, но в целом это не проблема. Тип void *
четко определен как универсальный указатель данных: это то, что возвращает malloc
, и он определен как легко конвертируемый в любой тип указателя на объект, то есть вам даже не нужно приведение. Так что это почти прекрасный выбор для типа возвращаемого значения dlsym
, за исключением небольшой проблемы с указателями на функции. malloc
никогда не сталкивался с этой проблемой (вы вряд ли когда-либо пытались бы изменить локализацию указателя на функцию), в то время как dlsym
всегда имеет эту проблему (символы, к которым вы обычно пытаетесь получить доступ в динамически загружаемых объектных файлах, представляют собой код, по крайней мере, так часто, как они данные). Но указатели на функции - это то, во что void *
не гарантируется преобразование, поэтому вы, скорее всего, получите предупреждения, поэтому вам нужны приведения, и вы можете получить предупреждения в -pedantic
даже при приведении типов.
person
Steve Summit
schedule
20.07.2015
dlsym()
немного непрозрачной в этом отношении, но если кто-то может просветить меня на странице руководства, это также поможет. - person lord.garbage   schedule 21.07.2015gcc
иclang
. - person lord.garbage   schedule 21.07.2015dlfsym
именно для этой цели (но это не было принято). - person Basile Starynkevitch   schedule 12.07.2017typedef
подписи, например здесь - person Basile Starynkevitch   schedule 12.07.2017