PHP擴充調用C++靜態庫

來源:互聯網
上載者:User

標籤:stand   strong   第一個   順序   loaded   地方   定義   自己   手動   

概述

      php通過擴充方式,調用c++源碼,這樣做的理由有很多,當你搜到這篇文章時,相信你已經有自己的考慮了。

寫這篇部落格的理由有二:

  1. 整理下php擴充調用c++代碼的過程。嗯,對,網上有很多類似的文章,不過對於php擴充c++的方式,很多文章在關鍵的地方並沒有說明,或者說,大部分都是擴充調用c代碼的。
  2. 已經兩年有餘沒寫部落格了,在這2017剛開始的時候,開個部落格,開始新的旅程,也是不錯的,哈哈。

 

大概目錄
  • c++編譯靜態庫
  • php 擴充編輯
  • 結語

註:下面步驟的作業環境——系統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_JANUARYBEGIN_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./configuremakemake 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 => disabledConfiguration File (php.ini) Path => /usr/local/etc/php/5.6Loaded 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^)/~),如果有錯誤的地方,歡迎指正。

  同時,剛開始做的時候,可能會碰到這樣那樣的問題,希望你最終能順利完成!當然,如果這篇部落格能對你有一點點協助的話,就更好了.

PHP擴充調用C++靜態庫

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.