奇怪的错误:在Windows上使用PHP7进行编译时未解析的符号

时间:2016-03-17 12:56:17

标签: php shared-libraries static-libraries unresolved-external

我有一个奇怪的问题:我有一个项目,它使用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中。所以,据我所知,我应该看一下,如果这个文件是在libdll文件中导出的。所以倾销出口给了我(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缺失。

但问题尚未解决

2 个答案:

答案 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)。

enter image description here