我有一个奇怪的问题:我有一个项目,它使用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)
我确信,我正在对lib
进行操作,因为重命名lib会给我一个错误,lib
缺失。
但问题尚未解决
答案 0 :(得分:2)
您需要将项目更新到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" sign(@@)后跟参数列表中的字节数(十进制)
答案 1 :(得分:2)
我在Visual Studio 2017社区中遇到类似的问题:
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)。