奇怪的错误:在 Windows 上使用 PHP7 编译时无法解析符号

Strange error: unresolved symbol when compiling with PHP7 on Windows

提问人:devopsfun 提问时间:3/17/2016 最后编辑:Xerkusdevopsfun 更新时间:11/23/2017 访问量:1099

问:

我有一个奇怪的问题:我有一个项目,其中使用了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。此行位于文件 中。所以,据我所知,我应该看看,这个文件是否导出到 or 文件中。所以倾销出口给了我(对于):zend_alloc.hlibdlllib

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 进行操作,因为重命名库会给我一个错误,即缺少。liblib

但问题还没有解决

php 共享库 static-libraries 未解析的外部

评论

0赞 Stef 9/9/2020
使用 --enable-debug 编译 PHP 意味着 ZEND_DEBUG=1,因此您的所有扩展也应该设置此标志......

答:

2赞 Andrew Stivenson 4/5/2016 #1

您需要将项目更新为 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”符号 (@@) 为后缀,后跟参数列表中的字节数(十进制)

2赞 Anos K. Mhazo 11/23/2017 #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)。

enter image description here