程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> 關於C++ >> PHP擴展調用C++靜態庫

PHP擴展調用C++靜態庫

編輯:關於C++

PHP擴展調用C++靜態庫。本站提示廣大學習愛好者:(PHP擴展調用C++靜態庫)文章只能為提供參考,不一定能成為您想要的結果。以下是PHP擴展調用C++靜態庫正文


概述

      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_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^)/~),假如有錯誤的中央,歡送指正。

  同時,剛開端做的時分,能夠會碰到這樣那樣的問題,希望你最終能順利完成!當然,假如這篇博客能對你有一點點協助的話,就更好了.

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved