在Windows上編譯PHP向外延展群組件的問題
?
這兩天需要編譯一個PHP擴充來實現特定的功能,參考了網上N多文章,最後發現兩件寶貝,其一是php_screw,另外一件是Cygwin。
首先編譯php_screw,以便有個感性的印象,編譯通過沒問題,然後自己試圖往裡增加一些代碼,磕磕碰碰地最後也編譯成功了。可是放到Apache上試用時,卻經常出現記憶體讀寫異常,修修改改了好久還沒無法解決。
於是,想自己重頭開始做,參考php_screw往裡一點點添代碼,看看能不能解決問題。
根據網上教程,在Cygwin裡用命令:
?php ext_skel_win32.php --extname=mytest
產生測試用程式架構,然後直接編譯架構,一切都很順利,再往裡增加一個功能函數,放到Apache測試,也都正常,但到了往下面兩個函數:
PHP_MINIT_FUNCTION(mytest)
和
PHP_MSHUTDOWN_FUNCTION(mytest)
的 return SUCCESS 前面增加
CG(extended_info) = 1;
,然後再編譯,則出現了編譯錯誤:
Deleting intermediate files and output files for project 'mytest - Win32 Debug_TS'.--------------------Configuration: mytest - Win32 Debug_TS--------------------Compiling...mytest.cLinking... Creating library Debug_TS/php_mytest.lib and object Debug_TS/php_mytest.expmytest.obj : error LNK2001: unresolved external symbol _compiler_globals_id..\..\Debug_TS/php_mytest.dll : fatal error LNK1120: 1 unresolved externalsError executing link.exe.Creating browse info file...php_mytest.dll - 2 error(s), 0 warning(s)
?
網上搜尋了好久,我試了都不行,所以懷疑是編譯器配置的問題,於是開啟php_screw和mytest兩個工程,對編譯參數一項項比對,最後發現:
自動產生的編譯參數如下Project --> Setting --> C/C++ -->Preprocessor definitions::
ZEND_DEBUG=1,WIN32,NDEBUG,_WINDOWS,_MBCS,_USRDLL,MYTEST_EXPORTS, COMPILE_DL_MYTEST,ZTS=1,ZEND_WIN32,PHP_WIN32,HAVE_MYTEST=1,LIBZEND_EXPORTS
而php_screw的對應參數則如下:
ZEND_DEBUG=0,WIN32,NDEBUG,_WINDOWS,_MBCS,_USRDLL,SCREW_EXPORTS, COMPILE_DL_SCREW, ZTS=1,ZEND_WIN32,PHP_WIN32,HAVE_SCREW=1
,對比可以發現:
1、自動產生架構的 ZEND_DEBUG=1, 而php_screw的 ZEND_DEBUG=0;
2、自動產生架構的參數中多一個 LIBZEND_EXPORTS ;
我於是對這兩個參數分別測試:
1、把 ZEND_DEBUG=1 改成 ZEND_DEBUG=0,再編譯,報錯如下:
Deleting intermediate files and output files for project 'mytest - Win32 Debug_TS'.--------------------Configuration: mytest - Win32 Debug_TS--------------------Compiling...mytest.cLinking... Creating library Debug_TS/php_mytest.lib and object Debug_TS/php_mytest.expmytest.obj : error LNK2001: unresolved external symbol _compiler_globals_id..\..\Debug_TS/php_mytest.dll : fatal error LNK1120: 1 unresolved externalsError executing link.exe.Creating browse info file...php_mytest.dll - 2 error(s), 0 warning(s)
?
2、再把 LIBZEND_EXPORTS 去掉,再編譯,錯誤消失:
Deleting intermediate files and output files for project 'mytest - Win32 Debug_TS'.--------------------Configuration: mytest - Win32 Debug_TS--------------------Compiling...mytest.cLinking... Creating library Debug_TS/php_mytest.lib and object Debug_TS/php_mytest.expCreating browse info file...php_mytest.dll - 0 error(s), 0 warning(s)
?
3、再把 ZEND_DEBUG=0 重新改成 ZEND_DEBUG=1,再編譯,無錯:
Deleting intermediate files and output files for project 'mytest - Win32 Debug_TS'.--------------------Configuration: mytest - Win32 Debug_TS--------------------Compiling...mytest.cLinking... Creating library Debug_TS/php_mytest.lib and object Debug_TS/php_mytest.expCreating browse info file...php_mytest.dll - 0 error(s), 0 warning(s)
?
所以,問題是由於 LIBZEND_EXPORTS 參數引起的,但由於對VC不熟且對Zend API更面生的緣故,只能是知其然而不可知其所以然也;