這兩天須要編譯一個PHP擴展來實現特定的功能,參考了網上N多文章,最後發現兩件寶貝,其一是php_screw,另一件是Cygwin。網站推廣
首先編譯php_screw,以便有個感性的印象,編譯經過沒問題,而後本身試圖往裏增長一些代碼,磕磕碰碰地最後也編譯成功了。但是放到Apache上試用時,卻常常出現內存讀寫異常,修修改改了很久還沒沒法解決。php
因而,想本身重頭開始作,參考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.c
- Linking...
- Creating library Debug_TS/php_mytest.lib and object Debug_TS/php_mytest.exp
- mytest.obj : error LNK2001: unresolved external symbol _compiler_globals_id
- ..\..\Debug_TS/php_mytest.dll : fatal error LNK1120: 1 unresolved externals
- Error 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
,對比能夠發現:
一、自動生成框架的 ZEND_DEBUG=1, 而php_screw的 ZEND_DEBUG=0;
二、自動生成框架的參數中多一個 LIBZEND_EXPORTS ;
我因而對這兩個參數分別測試:
一、把 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.c
- Linking...
- Creating library Debug_TS/php_mytest.lib and object Debug_TS/php_mytest.exp
- mytest.obj : error LNK2001: unresolved external symbol _compiler_globals_id
- ..\..\Debug_TS/php_mytest.dll : fatal error LNK1120: 1 unresolved externals
- Error executing link.exe.
- Creating browse info file...
-
- php_mytest.dll - 2 error(s), 0 warning(s)
二、再把 LIBZEND_EXPORTS 去掉,再編譯,錯誤消失:測試
- Deleting intermediate files and output files for project 'mytest - Win32 Debug_TS'.
- --------------------Configuration: mytest - Win32 Debug_TS--------------------
- Compiling...
- mytest.c
- Linking...
- Creating library Debug_TS/php_mytest.lib and object Debug_TS/php_mytest.exp
- Creating browse info file...
-
- php_mytest.dll - 0 error(s), 0 warning(s)
三、再把 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.c
- Linking...
- Creating library Debug_TS/php_mytest.lib and object Debug_TS/php_mytest.exp
- Creating browse info file...
-
- php_mytest.dll - 0 error(s), 0 warning(s)
因此,問題是因爲 LIBZEND_EXPORTS 參數引發的,但因爲對VC不熟且對Zend API更面生的緣故,只能是知其然而不可知其因此然也;網站推廣。(fblww-0113)spa