У меня странная проблема: у меня есть проект, который использует PHP7 (php7ts.lib
) в этом.
PHP7 скомпилирован самостоятельно с VS 2015:
--enable-mbstring=static --with-gd=static --with-iconv=static
--enable-soap --enable-sockets --disable-ipv6 --with-dom
--disable-bcmath --disable-cgi --disable-cli --enable-embed
--with-bz2=static --enable-com-dotnet --enable-ctype
--enable-mbregex=static --disable-mbregex-backtrack --enable-odbc --with-mp
То же самое с более уменьшенным количеством параметров:
--disable-all --without-libxml --without-dom --enable-sockets
--enable-embed --enable-com-dotnet --enable-ctype --enable-odbc
--enable-debug
BZip2 тоже скомпилирован сам и работает. Компиляция PHP7 также работает, я получаю .lib
а также .dll
файл. Затем я компилирую проект и получаю странные ошибки:
error LNK2019: unresolved external symbol __imp__emalloc@@4 referenced in function
unresolved external symbol __imp__efree@@4
unresolved external symbol __imp__zval_dtor_func@@4
unresolved external symbol __imp__convert_to_string@@4
fatal error LNK1120: 4 unresolved externals
Проблема в том, что с VS2013 и PHP 5.6, скомпилированными мной, все работало. Странно то, что неразрешенные символы указывают на то, что не выглядит специфичным для библиотеки.
Я использую deps отсюда: http://windows.php.net/downloads/php-sdk/deps-7.0-vc14-x86.7z
Я знаю, что мне чего-то не хватает, но из этих сообщений я не вижу, чего мне не хватает.
Изменить: некоторые новые — возможно, полезные — идеи
Хорошо, теперь я могу получить больше информации, может быть, это поможет нам найти решение.
Во-первых, я строю это в режиме отладки с 32-битной архитектурой.
В cpp
файл, есть эти строки (в качестве примера для __imp__efree@@4
ошибка:
#if PHP_VERSION_ID >= 70000
# define FREE_ZVAL(z) efree_rel(z)
#endif
Когда я собираюсь к определению efree_rel(z)
Я вижу эту строку (которая имеет отношение к Zend
):
#define efree_rel(ptr) _efree((ptr) ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_CC)
Собираюсь к определению _efree
, Я вижу это:
ZEND_API void ZEND_FASTCALL _efree(void *ptr ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC);
Это означает, что эта функция взята из PHP7 / Zend. Эта строка была в файле zend_alloc.h
, Итак, насколько я знаю, я должен посмотреть, если этот файл экспортируется в lib
или же dll
файл. Таким образом, вывоз экспорта дает мне (для lib
):
Dump of file php7ts_debug.lib
File Type: LIBRARY
Exports
ordinal name
_efree@@20
И для dll
:
Dump of file php7ts_debug.dll
File Type: DLL
Section contains the following exports for php7ts_debug.dll
00000000 characteristics
56EAF08F time date stamp Thu Mar 17 18:59:43 2016
0.00 version
1 ordinal base
1531 number of functions
1531 number of names
ordinal hint RVA name
192 18 0028FFE0 _efree@@20 = @ILT+24528(_efree@@20)
Я уверен, что я работаю на Corrent lib
потому что переименование библиотеки дает мне ошибку, что lib
пропал, отсутствует.
Но проблема еще не решена
Вам необходимо обновить проект до проекта VS2015.
Все неразрешенные функции имеют соглашение о вызовах ZEND_FASTCALL (zend_portability.h):
#if defined(__GNUC__) && ZEND_GCC_VERSION >= 3004 && defined(__i386__)
# define ZEND_FASTCALL __attribute__((fastcall))
#elif defined(_MSC_VER) && defined(_M_IX86) && _MSC_VER == 1700
# define ZEND_FASTCALL __fastcall
#elif defined(_MSC_VER) && _MSC_VER >= 1800 && !defined(__clang__)
# define ZEND_FASTCALL __vectorcall
#else
# define ZEND_FASTCALL
#endif
Статическая библиотека php7ts.lib была собрана с использованием соглашений о вызовах VS2015 и __vectorcall (https://msdn.microsoft.com/en-us/library/dn375768.aspx):
К именам функций добавляются два знака «at» (@@), за которыми следует число байтов (в десятичной дроби) в списке параметров.
У меня была похожая проблема в Visual Studio 2017 Community, выдающая ошибку:
error LNK2019: unresolved external symbol __imp__emalloc@@40 referenced in function "struct _zend_string * __cdecl zend_string_alloc(unsigned __int64,int)" (?zend_string_alloc@@YAPEAU_zend_string@@_KH@Z)
Решение, которое работало для меня, должно было установить Zend_Debug до 0
#define ZTS 1
//#define PHP_COMPILER_ID "VC14"#define ZEND_WIN32 1
#define PHP_WIN32 1
#define ZEND_DEBUG 0
/*
#ifdef _DEBUG
#define ZEND_DEBUG 1
#else
#define ZEND_DEBUG 0
#endif
*/
Также убедитесь, что в свойствах вашего проекта для генерации кода установлено значение Многопоточная отладка (/ MTd).