乙個需求要接入公司內部的乙個基於protobuf協議的介面,protobuf的庫檔案都是proto編譯器生成的cpp檔案。要編譯成php擴充套件的話,需要c/c++混編,這裡記錄一下。
1、公升級一下安裝的protobuf,貌似c1的機器上的protobuf都是2.4.0的,當編譯高階的一些語法的proto檔案的時候都會報錯的,公升級到2.5.0以上的版本好些。
2、proto編譯器會根據proto檔案生成相關的cc檔案,裡面包含著訊息體的一些操作函式,比如解包,造包,序列化,反序列化之類的函式,反正很豐富。你需要把他們編譯進你的php擴充套件裡面,所以你得自己編譯成靜態庫檔案(.a檔案),記得要加-fpic選項,否則會報:relocation r_x86_64_32 against `.rodata』 can not be used when ****** a shared object; recompile with -fpic。
3、要用到pb的內建api,上一步咱們生成的cc檔案裡面有些方法和函式是protobuf的全域性函式,需要這個protobuf.a檔案的支援。這時候你需要把protobuf的靜態庫一起編譯進去,通常是protobuf.a檔案(好奇為啥不是libprotobuf.a),所以在編譯整個php擴充套件的時候,會報出這個錯誤:could not read symbols: bad value,好吧,應該是在編譯要鏈結的靜態庫的時候沒加上-fpic選項。需要重新編譯一下,但是看了一下protobuf的makefile,大的嚇人,改起來豈不是很坑爹。所以直接從configure檔案改好了,在用configure生成makefile的時候直接加上選項–enable-static=yes就好了。
4、因為涉及到c/c++混編,所以需要指定一下confg.m4的一些引數。
php_require_cxx() :次擴充套件要用到c++.
php_add_library(stdc++, 1, extra_ldflags) :因為咱們的php擴充套件是cpp檔案,而php的擴充套件makefile檔案指定使用的是gcc,用gcc去編譯cpp檔案,(編譯階段的gcc和g++都是等價的,所以cpp檔案在這裡還是由gcc去編譯,但是鏈結就不一樣了),會因為gcc無法直接鏈結cpp庫檔案而導致錯誤,所以需指定g++來鏈結,所以就得指定stdc++了。
php_add_library_with_path : 指定你庫檔案的目錄了,相當於直接編譯的時候加上-ixx.a -i/usr/local/include/***之類的了。
至於需不需要在cpp檔案的部分加上extern 「c」 ,我覺得無所謂啊,反正編譯階段gcc/g++的行為都一致的,只是鏈結方式不一樣而已。
然後就開始編譯吧。
關於protobuf的一些總結
最近面試中被問protobuf的加解碼原理,非常的尷尬,因為我沒了解過,這裡稍作總結 proto檔案 每乙個proto檔案其實對應著我們正常的乙個模型 也就是model 只是proto檔案是用來描述這樣的乙個模型的檔案,並非實際上的工程model。舉個例子,檔案person.proto messag...
一些擴充套件知識
apache nignx是靜態伺服器 http server nginx優點 負載均衡 反向 處理靜態檔案優勢。nginx處理靜態請求的速度高於apache apache優點 相對於tomcat伺服器來說處理靜態檔案是它的優勢,速度快。apache是靜態解析,適合靜態html 等。http serv...
一些擴充套件kmp的總結
花了一天多時間學了下ex kmp。可以看劉雅瓊的 ppt,講的非常清楚 我的寫法是 next i p i.m 1 與 p 0.m 1 的最長公共字首 ex i t i.n 1 與 p 0.m 1 的最長公共字首 我的小模板 html view plain copy 擴充套件kmp next i p ...