Как проверить исправление символа C ++ при создании расширения PHP? - PullRequest
3 голосов
/ 28 апреля 2009

У меня есть модуль PHP, написанный на C ++, который опирается на устанавливаемую библиотеку C ++ (Boost Date_Time).

В настоящее время в моем файле config.m4 я проверяю библиотеку следующим образом:

  LIBNAME=boost_date_time
  LIBSYMBOL=_ZN5boost9gregorian9bad_monthD0Ev

  PHP_CHECK_LIBRARY($LIBNAME,$LIBSYMBOL,,
  [
    AC_MSG_ERROR([lib $LIBNAME not found.  Try: sudo apt-get install libboost-dev])
  ],[
    -lstdc++ -ldl
  ])

Теперь, это работает в моей текущей среде, но я до боли осознаю, что это, вероятно, сломает другую версию библиотеки или компилятора.

Как я могу заставить automake понять не искаженный символ C ++?

Edit:

Я понимаю, что проверка искаженного имени ужасна, но нет ли способа проверить имя символа, возвращаемое "nm -C" (например, boost :: gregorian :: bad_month и т. Д.).

Я нашел некоторые ссылки на команду automake AC_LANG_CPLUSPLUS (), но я не уверен, как ее использовать и применимо ли это здесь.

Ответы [ 4 ]

2 голосов
/ 14 мая 2009

Вы можете проверить AC_TRY_COMPILE примерно так:

LIBNAME=boost_date_time
AC_MSG_CHECKING([for BOOST])
AC_TRY_COMPILE(
[
#include "boost/date_time/gregorian/greg_month.hpp"
],
[
boost::gregorian::bad_month* bm = new boost::gregorian::bad_month;
],
[
AC_MSG_RESULT(yes)
],
[
AC_MSG_ERROR([lib $LIBNAME not found.  Try: sudo apt-get install libboost-dev])
])

Это позволяет избежать использования неупорядоченного символа.

0 голосов
/ 28 апреля 2009

Вам необходимо предоставить набор оболочек C ++ для API-функций Boost, которые вы хотите вызывать. Эти обертки должны быть объявлены с extern "C", как в:

extern "C" 
void foo(int bar) 
{
...
}

Ваш PHP-код должен использовать эти оболочки, а не пытаться напрямую вызывать методы C ++.

РЕДАКТИРОВАТЬ : Поскольку вы предполагаете наличие automake, вы, вероятно, планируете скомпилировать библиотеку Boost как часть установки. Это дает вам возможность проверить результат искажения имени. Попробуйте создать тестовую программу C ++ по этим направлениям. Обратите внимание, что это нужно только для компиляции ; он не должен давать правильный результат.

#include "boost/date_time/gregorian/greg_month.hpp"
int main( int argc, const char* argv[] )
{
   boost::gregorian::bad_month* xxxjunk = new boost::gregorian::bad_month;
   return 0;
}

В вашем автомате, вы хотите скомпилировать это, а затем запустить вывод через

nm -C | grep "boost::gregorian::bad_month"

В зависимости от ваших потребностей и выбора, вы можете захотеть еще больше уточнить команду grep для поиска строки "typeinfo for boost::gregorian::bad_month" (обратите внимание, что это еще больше увеличивает вашу зависимость от конкретной реализации компилятора.)

0 голосов
/ 28 апреля 2009

Это ужасная идея - изуродовать символы под открытым небом. Зачем вам это нужно в первую очередь?

Увидев ваше обновление, я должен спросить, почему бы не использовать пользовательское правило для вызова nm, получить эту информацию и сделать это правило обязательным для выполнения? Я был бы очень удивлен, если бы autoconf предоставил прямую команду для проверки объектных файлов на наличие символов.

0 голосов
/ 28 апреля 2009

Вне среды конкретного компилятора C ++ не существует «не искаженного символа C ++» - сортировка выполняется точно для предоставления уникального имени внешним инструментам, таким как компоновщики и библиотекари.

...