PHP擴展調用C++靜態庫。本站提示廣大學習愛好者:(PHP擴展調用C++靜態庫)文章只能為提供參考,不一定能成為您想要的結果。以下是PHP擴展調用C++靜態庫正文
php經過擴展方式,調用c++源碼,這樣做的理由有很多,當你搜到這篇文章時,置信你曾經有自己的思索了。
寫這篇博客的理由有二:
大約目錄
注:上面步驟的操作環境——零碎macOS10.12.2,PHP版本 5.6.29.
c++編譯靜態庫頭文件:hello.h
#include<string> std::string hello_joint(std::string a, std::string b);
完成頭文件定義的函數:hello.cpp
#include "hello.h" std::string hello_joint(std::string a, std::string b) { std::string str = a+b; return str; }
生成hello.o文件
g++ -c hello.cpp
生成靜態庫libhello.a文件
ar -r libhello.a hello.o
寫個復雜的test.cpp測試下:
1 #include<iostream> 2 #include "hello.h" 3 int main() 4 { 5 std::string a = std::string("Hello "); 6 std::string b = std::string("World!"); 7 std::cout<<hello_joint(a, b)<<std::endl; 8 return 0; 9 }
編譯
g++ test.cpp libhello.a
運轉
./a.out
終端輸入
Hello World!
這樣,你的c++靜態庫制造完成。
php 擴展編輯
假如要編輯php擴展,需求下載php源碼,這裡下載的是php-5.6.16。寫文章的時分,才發現php源碼版本和零碎的php版本不分歧。由於是先下載的php源碼,然後經過brew install php56,不過,影響不大,不必糾結。
運轉如下命令,發生擴展文件夾january。
./ext_skel --extname=january
命名為january,次要是不想跟c++源碼hello發生任何關系,以免前面混雜,當然,也是由於想不出其他比擬好的名字。
首先編輯config.m4,需求改的中央大約歸結為三處:
1、找到如下三行,並把後面的正文dnl去掉。
PHP_ARG_ENABLE(january, whether to enable january support,
Make sure that the comment is aligned:
[ --enable-january Enable january support])
2、找到如下的代碼,並在它的上面加上相應代碼,以支持c++調用。
if test "$PHP_JANUARY" != "no"; then dnl Write more examples of tests here...
要加上的相應代碼,留意其中的參數名。
if test "$PHP_JANUARY" != "no"; then dnl Write more examples of tests here... PHP_ADD_INCLUDE(./include) PHP_ADD_LIBRARY(stdc++, 1, JANUARY_SHARED_LIBADD) PHP_ADD_LIBRARY_WITH_PATH(hello, ./lib, JANUARY_SHARED_LIBADD) PHP_REQUIRE_CXX() PHP_SUBST(JANUARY_SHARED_LIBADD)
3、同時,在該函數的最後一行,把january.c改為january.cpp
PHP_NEW_EXTENSION(january, january.cpp, $ext_shared)january.cpp需求做的任務比擬多:
1、重命名:把january.c改為為january.cpp;
2、在兩處中央加上EXTERN "C"標識,這點不要忘了:
第一處加extern "C"{},並在上面加上需求的c++頭文件:
extern "C" { #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "php.h" #include "php_ini.h" #include "ext/standard/info.h" #include "php_january.h" } #include<string> #include "hello.h"
第二處加BEGIN_EXTERN_C()和END_EXTERN_C():
#ifdef COMPILE_DL_JANUARY BEGIN_EXTERN_C() ==>添加的 ZEND_GET_MODULE(january) END_EXTERN_C() ==>添加的 #endif
3、在如下的中央,參加函數稱號,可以了解為php要調用的函數的聲明:
const zend_function_entry january_functions[] = { PHP_FE(confirm_january_compiled, NULL) /* For testing, remove later. */ PHP_FE(january_say, NULL) PHP_FE_END /* Must be the last line in january_functions[] */ };
4、留意到january.cpp中,它編寫了一個函數例子confirm_january_compiled,如今,我們也需求完成january_say的函數完成,它接納來自php的參數,並在函數中調用c++函數。
PHP_FUNCTION(january_say) { char *arg1 = NULL, *arg2 = NULL; int arg1_len, arg2_len; int argc = ZEND_NUM_ARGS(); if(zend_parse_parameters(argc TSRMLS_CC, "ss", &arg1, &arg1_len, &arg2, &arg2_len) == FAILURE) return; std::string a = std::string(arg1); std::string b = std::string(arg2); std::string res = hello_joint(a, b); RETURN_STRING(res.c_str(), res.length()); }
完成這些步驟之後,剩下的任務就少多了。
要接下去做其他步驟的話,建議先做兩個拷貝舉措:
1,新建lib文件夾,將之前制造的libhello.a拷貝到lib裡;
2,新建include文件夾(也可以等到./configure的時分,它會幫你創立這個文件夾),將hello.h頭文件拷貝到這裡。
應用php工具,按順序運轉如下四個命令:
phpize ./configure make make install
注:假如兩頭修正了順序代碼什麼的,記得要從第一個phpize重新執行來過。
運轉正常的話,january.so會裝置到.../lib/php/extensions/no-debug-non-zts-20131226/目錄下。
最後,需求加載january.so,次要是改配置php.ini。假如不知道這個文件在哪的話,你可以在php順序中輸入(echo phpinfo())。
echo phpinfo()的輸入,可以看到指明了php.ini的所在目錄。 Virtual Directory Support => disabled Configuration File (php.ini) Path => /usr/local/etc/php/5.6 Loaded Configuration File => /usr/local/etc/php/5.6/php.ini
首先,找到enable_dl,改為On;
enable_dl = On --在php.ini 中開啟php靜態加載dl
再找到有很多extension=xxxxxx.so的中央,添加上面句子,加載靜態庫,當然也可以在順序中手動加載。
extension=january.so
在php順序中測試:
echo january_say("hello ", "world!");
輸入:
hello world!結語
快過年了,都不能靜心的好好寫博客了(真的是程度不夠,經歷無限的極好借口\(^o^)/~),假如有錯誤的中央,歡送指正。
同時,剛開端做的時分,能夠會碰到這樣那樣的問題,希望你最終能順利完成!當然,假如這篇博客能對你有一點點協助的話,就更好了.