3

I have a strange problem: I have a project, which uses PHP7 (php7ts.lib) in it.

PHP7 is compiled on my own with 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

The same with a more reduced number of parameters:

--disable-all --without-libxml --without-dom --enable-sockets 
--enable-embed --enable-com-dotnet --enable-ctype --enable-odbc
--enable-debug 

BZip2 is also compiled on my own and it works. Compilation of PHP7 also works, I get the .lib and .dll file. Then I am compiling the project and I am getting this strange errors:

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

The problem is: With VS2013 and PHP 5.6 compiled by my own, everything worked. The strange thing is, that the unresolved symbols point to something which does not look to be specific to a library.

I am using the deps from here: http://windows.php.net/downloads/php-sdk/deps-7.0-vc14-x86.7z

I know, that I am missing something, but from these message I cannot see what I am missing.

Edit: Some new - maybe helpful - insights

OK, I could now get some more information, maybe this help us to find a solution.

First, I am building this in Debug mode with 32 bit architecture.

In a cpp file, there are these lines (as an example for the __imp__efree@@4 error:

#if PHP_VERSION_ID >= 70000
    #   define FREE_ZVAL(z) efree_rel(z)
#endif

When I am going to the definition of efree_rel(z), I see this line (which has something to do with Zend):

#define efree_rel(ptr)                          _efree((ptr) ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_CC)

Going to definition of _efree, I see this:

ZEND_API void   ZEND_FASTCALL _efree(void *ptr ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC);

So that means, that this function is coming from PHP7/Zend. This line was in the file zend_alloc.h. So, as far as I know, I should look, if this file is exported in the lib or dll file. So dumping out exports gives me (for lib):

Dump of file php7ts_debug.lib
File Type: LIBRARY
     Exports
       ordinal    name
                  _efree@@20

And for 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)

I am sure, that I am operating on the corrent lib, because renaming the lib gives me an error, that the lib is missing.

But the problem is not resolved yet

Xerkus
  • 2,695
  • 1
  • 19
  • 32
devopsfun
  • 1,368
  • 2
  • 15
  • 37
  • Compiling PHP with --enable-debug means ZEND_DEBUG=1, so all your extensions should set this flag too... – Stef Sep 08 '20 at 21:35

2 Answers2

2

You need to update you project to VS2015 project. All unresolved functions has ZEND_FASTCALL calling convention (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

Static library php7ts.lib was build using VS2015 and __vectorcall calling convention (https://msdn.microsoft.com/en-us/library/dn375768.aspx):

Function names are suffixed with two "at" signs (@@) followed by the number of bytes (in decimal) in the parameter list

2

I had similar problem in Visual Studio 2017 Community producing error:

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)

Solution that worked for me was to set ZEND_DEBUG to 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
*/

Also make sure you set code generation to Multi-threaded Debug (/MTd) on your project properties.

enter image description here

Anos K. Mhazo
  • 365
  • 3
  • 11