![v2-d218a762a6106059636cbf385c371534_1440w.jpg?source=172ae18b](http://img-03.proxy.5ce.com/view/image?&type=2&guid=f07af407-3f30-eb11-8da9-e4434bdf6706&url=https://pic4.zhimg.com/v2-d218a762a6106059636cbf385c371534_1440w.jpg?source=172ae18b)
1、新建一个Linux项目
![v2-982199f9d76c43139c67c55bc5c1061d_b.jpg](http://img-01.proxy.5ce.com/view/image?&type=2&guid=f07af407-3f30-eb11-8da9-e4434bdf6706&url=https://pic2.zhimg.com/v2-982199f9d76c43139c67c55bc5c1061d_b.jpg)
2、选择项目类型为:Shared Library
![v2-601283fe6c3bf5209475dfbda458ae6b_b.jpg](http://img-03.proxy.5ce.com/view/image?&type=2&guid=f07af407-3f30-eb11-8da9-e4434bdf6706&url=https://pic4.zhimg.com/v2-601283fe6c3bf5209475dfbda458ae6b_b.jpg)
3、创建一个远程项目
![v2-323ec853eb7e376b8f0e0e67e477a860_b.jpg](http://img-01.proxy.5ce.com/view/image?&type=2&guid=f07af407-3f30-eb11-8da9-e4434bdf6706&url=https://pic1.zhimg.com/v2-323ec853eb7e376b8f0e0e67e477a860_b.jpg)
4、完成
![v2-50dc3b7898b2484cc30e8559a3172f32_b.jpg](http://img-02.proxy.5ce.com/view/image?&type=2&guid=f07af407-3f30-eb11-8da9-e4434bdf6706&url=https://pic3.zhimg.com/v2-50dc3b7898b2484cc30e8559a3172f32_b.jpg)
5、解决方案删除这两个文件
![v2-921360a5226fe6d518297b6198ed4568_b.jpg](http://img-02.proxy.5ce.com/view/image?&type=2&guid=f07af407-3f30-eb11-8da9-e4434bdf6706&url=https://pic1.zhimg.com/v2-921360a5226fe6d518297b6198ed4568_b.jpg)
![v2-4f7f771b521bf242553a7d1353c3fcae_b.jpg](http://img-01.proxy.5ce.com/view/image?&type=2&guid=f07af407-3f30-eb11-8da9-e4434bdf6706&url=https://pic3.zhimg.com/v2-4f7f771b521bf242553a7d1353c3fcae_b.jpg)
![v2-751e9a2a8d8773c355d127e795d5d44d_b.jpg](http://img-03.proxy.5ce.com/view/image?&type=2&guid=f07af407-3f30-eb11-8da9-e4434bdf6706&url=https://pic2.zhimg.com/v2-751e9a2a8d8773c355d127e795d5d44d_b.jpg)
![v2-4635c6584051c3dba5b98711a30f092b_b.jpg](http://img-02.proxy.5ce.com/view/image?&type=2&guid=f07af407-3f30-eb11-8da9-e4434bdf6706&url=https://pic4.zhimg.com/v2-4635c6584051c3dba5b98711a30f092b_b.jpg)
6、去php源码包的ext目录里生成一个php扩展框架,并拷贝两个文件:xxxx.c文件和xxxx.h头文件 使用命令:./ext_skel --extname=extension1
把这两个文件从虚拟机拿到开发环境来,并添加到项目里去
![v2-09d33fa301083466d708980c752997c9_b.jpg](http://img-02.proxy.5ce.com/view/image?&type=2&guid=f07af407-3f30-eb11-8da9-e4434bdf6706&url=https://pic2.zhimg.com/v2-09d33fa301083466d708980c752997c9_b.jpg)
拷贝到项目目录去
![v2-27d2b6ea8680d10c5c94d3e2059002eb_b.jpg](http://img-02.proxy.5ce.com/view/image?&type=2&guid=f07af407-3f30-eb11-8da9-e4434bdf6706&url=https://pic4.zhimg.com/v2-27d2b6ea8680d10c5c94d3e2059002eb_b.jpg)
再把这两个文件添加到项目里
可以直接拖进去或者添加现有项或者是复制粘贴都可以
![v2-b4844ce2be0dd6946096e8d81250b23d_b.jpg](http://img-02.proxy.5ce.com/view/image?&type=2&guid=f07af407-3f30-eb11-8da9-e4434bdf6706&url=https://pic2.zhimg.com/v2-b4844ce2be0dd6946096e8d81250b23d_b.jpg)
接下来会提示找不到某些头文件,不用担心,我们可以设置头文件目录
![v2-24d2d9b879a2b7e472df40aef6f747d0_b.jpg](http://img-03.proxy.5ce.com/view/image?&type=2&guid=f07af407-3f30-eb11-8da9-e4434bdf6706&url=https://pic1.zhimg.com/v2-24d2d9b879a2b7e472df40aef6f747d0_b.jpg)
在配置对话框选择:MakeFile Settings
![v2-2d011678e3b900355741d75afea73304_b.jpg](http://img-02.proxy.5ce.com/view/image?&type=2&guid=f07af407-3f30-eb11-8da9-e4434bdf6706&url=https://pic1.zhimg.com/v2-2d011678e3b900355741d75afea73304_b.jpg)
添加包含目录
![v2-9ff6faf24663768aba3a672aa22b22de_b.jpg](http://img-03.proxy.5ce.com/view/image?&type=2&guid=f07af407-3f30-eb11-8da9-e4434bdf6706&url=https://pic3.zhimg.com/v2-9ff6faf24663768aba3a672aa22b22de_b.jpg)
添加头文件目录如下:点+ 添加
![v2-767525843fea007184ed7044802525aa_b.jpg](http://img-02.proxy.5ce.com/view/image?&type=2&guid=f07af407-3f30-eb11-8da9-e4434bdf6706&url=https://pic3.zhimg.com/v2-767525843fea007184ed7044802525aa_b.jpg)
然后点OK 再Apply
![v2-2fb2e4948012a5ba54d03f42f0380b7e_b.jpg](http://img-03.proxy.5ce.com/view/image?&type=2&guid=f07af407-3f30-eb11-8da9-e4434bdf6706&url=https://pic3.zhimg.com/v2-2fb2e4948012a5ba54d03f42f0380b7e_b.jpg)
再OK 就可以了 在目录的外部依赖项可以看到我们添加的头文件
![v2-9e76db8a986277f519e099bfcefd485c_b.jpg](http://img-02.proxy.5ce.com/view/image?&type=2&guid=f07af407-3f30-eb11-8da9-e4434bdf6706&url=https://pic1.zhimg.com/v2-9e76db8a986277f519e099bfcefd485c_b.jpg)
一切准备工作就序,可以先编译试试 我们可以看到编译时没有错误的
也生成了相应的so共享库文件
![v2-03ab47b69b22c1b53edd9bac38feab6e_b.jpg](http://img-02.proxy.5ce.com/view/image?&type=2&guid=f07af407-3f30-eb11-8da9-e4434bdf6706&url=https://pic3.zhimg.com/v2-03ab47b69b22c1b53edd9bac38feab6e_b.jpg)
然后我们可以尝试在扩展源文件写点东西,我用的是VS2010,开发这个很方便,有强大的智能提示
![v2-0db2950c2fc4e7281b427de24b519756_b.jpg](http://img-02.proxy.5ce.com/view/image?&type=2&guid=f07af407-3f30-eb11-8da9-e4434bdf6706&url=https://pic3.zhimg.com/v2-0db2950c2fc4e7281b427de24b519756_b.jpg)
好,重点来了,现在我们可以试着去把我们刚才编译的文件加入到php.ini中的 extension中看看效果 因为我们刚才建立的是远程项目,所以在自己的虚拟机中可以找到这个项目目录:
![v2-7bde05d2b24a93c142f9540615c50cd8_b.jpg](http://img-03.proxy.5ce.com/view/image?&type=2&guid=f07af407-3f30-eb11-8da9-e4434bdf6706&url=https://pic1.zhimg.com/v2-7bde05d2b24a93c142f9540615c50cd8_b.jpg)
当然这个目录可以自定义,大家可以去试试 接下来,我们进这个项目目录看看
![v2-3eb8c7dae966ffcad031915d3134a474_b.jpg](http://img-02.proxy.5ce.com/view/image?&type=2&guid=f07af407-3f30-eb11-8da9-e4434bdf6706&url=https://pic1.zhimg.com/v2-3eb8c7dae966ffcad031915d3134a474_b.jpg)
源文件什么的都在我们编译的时候自动上传到了这个远程目录里,然后呢,我们的so文件在 Debug目录里,因为我们在VS中的 项目类型是Debug版本的
![v2-770606423a492c27135fdaeaf1eb4bd5_b.jpg](http://img-02.proxy.5ce.com/view/image?&type=2&guid=f07af407-3f30-eb11-8da9-e4434bdf6706&url=https://pic2.zhimg.com/v2-770606423a492c27135fdaeaf1eb4bd5_b.jpg)
我们已经看到了这个so文件,那接下来我们要试着去把这个so文件复制到php的extension目录中去
我这边的路径是:/usr/local/php/lib/php/extensions/no-debug-non-zts-20170718
接下来cp吧
![v2-a0c7d76f8627ec913e2b376958f8682b_b.jpg](http://img-02.proxy.5ce.com/view/image?&type=2&guid=f07af407-3f30-eb11-8da9-e4434bdf6706&url=https://pic4.zhimg.com/v2-a0c7d76f8627ec913e2b376958f8682b_b.jpg)
OK,文件已经成功复制过了
![v2-cd6159d2b4e47df7e794873699f26175_b.jpg](http://img-01.proxy.5ce.com/view/image?&type=2&guid=f07af407-3f30-eb11-8da9-e4434bdf6706&url=https://pic2.zhimg.com/v2-cd6159d2b4e47df7e794873699f26175_b.jpg)
接下来我们把这个库文件添加到php.ini中
![v2-dc0c389f949b6e3b19b1066db0f329fc_b.jpg](http://img-02.proxy.5ce.com/view/image?&type=2&guid=f07af407-3f30-eb11-8da9-e4434bdf6706&url=https://pic1.zhimg.com/v2-dc0c389f949b6e3b19b1066db0f329fc_b.jpg)
保存,然后重启php-fpm看看效果吧。
重点来了,我们会看到一个提示: PHP Startup: Invalid library (maybe not a PHP library)
'Extension1.so' in <b>Unknown</b>
意思就是我们刚才编译的so文件不是一个php扩展,为什么呢?我们用的也是php为我们生成的代码,还有什么不对呢?那么接 下来,
咱们去php源码找寻下答案吧
![v2-3c59f9f036a500202771bda2be4d1dff_b.jpg](http://img-01.proxy.5ce.com/view/image?&type=2&guid=f07af407-3f30-eb11-8da9-e4434bdf6706&url=https://pic4.zhimg.com/v2-3c59f9f036a500202771bda2be4d1dff_b.jpg)
我们可以通过搜索 刚才那个提示的 字符串 很容易找到 那个输出错误信息的 源文件 在 php-
7.2.28extstandarddl.c 中的 195行
![v2-37544dbdfe1870fbd8a92bfe49c34d97_b.jpg](http://img-03.proxy.5ce.com/view/image?&type=2&guid=f07af407-3f30-eb11-8da9-e4434bdf6706&url=https://pic4.zhimg.com/v2-37544dbdfe1870fbd8a92bfe49c34d97_b.jpg)
那么是什么原因呢?我们可以通过阅读代码,得知: 首先,会加载我们刚才的so文件
![v2-57a6b1e77e3db3537abbb0695d25818f_b.jpg](http://img-02.proxy.5ce.com/view/image?&type=2&guid=f07af407-3f30-eb11-8da9-e4434bdf6706&url=https://pic4.zhimg.com/v2-57a6b1e77e3db3537abbb0695d25818f_b.jpg)
得到一个内核对象,所谓的句柄的玩意儿,不晓得句柄的无所谓,反正你晓得这个是后续我们要操作这个so文件的一把钥匙就行 了
接下来是一顿判断操作,没有问题就会去执行这个地方:
![v2-774c9800b02238a4af9609e1c011634c_b.jpg](http://img-01.proxy.5ce.com/view/image?&type=2&guid=f07af407-3f30-eb11-8da9-e4434bdf6706&url=https://pic1.zhimg.com/v2-774c9800b02238a4af9609e1c011634c_b.jpg)
这个意思是调用我那个so文件导出的一个方法:get_module,
然后返回一个结构体指针,这个结构体是:_zend_module_entry。 晓得原因就好办了,所以我们可以去我们刚才那个扩展的源文件看看有没有这样的方法,我们找遍了源文件,只发现这个:
![v2-417b3c3f434e13fb5d8ec15ea5398e07_b.jpg](http://img-02.proxy.5ce.com/view/image?&type=2&guid=f07af407-3f30-eb11-8da9-e4434bdf6706&url=https://pic4.zhimg.com/v2-417b3c3f434e13fb5d8ec15ea5398e07_b.jpg)
也就是我们没有去调用这个:ZEND_GET_MODULE(extension1),而这个要调用的话是需要通过一个宏来控制的 那怎么才能调用呢?很简单,我们只需要在编译的时候加上宏就可以了:
![v2-8249b98a46e4f4fb49a14e369293f89a_b.jpg](http://img-02.proxy.5ce.com/view/image?&type=2&guid=f07af407-3f30-eb11-8da9-e4434bdf6706&url=https://pic3.zhimg.com/v2-8249b98a46e4f4fb49a14e369293f89a_b.jpg)
双击打开:
![v2-250195aba1af9ee611e004f2da7cd067_b.jpg](http://img-03.proxy.5ce.com/view/image?&type=2&guid=f07af407-3f30-eb11-8da9-e4434bdf6706&url=https://pic4.zhimg.com/v2-250195aba1af9ee611e004f2da7cd067_b.jpg)
我们可以加上这个宏:
![v2-4d95fc78a66dd2249644391643bbcf04_b.jpg](http://img-02.proxy.5ce.com/view/image?&type=2&guid=f07af407-3f30-eb11-8da9-e4434bdf6706&url=https://pic1.zhimg.com/v2-4d95fc78a66dd2249644391643bbcf04_b.jpg)
再次编译,我们可以看到编译成功
![v2-92a37cdef480b18337e0f6a4d7aab2ab_b.jpg](http://img-03.proxy.5ce.com/view/image?&type=2&guid=f07af407-3f30-eb11-8da9-e4434bdf6706&url=https://pic4.zhimg.com/v2-92a37cdef480b18337e0f6a4d7aab2ab_b.jpg)
我们自定义宏也加上了
gcc -ggdb -ffunction-sections -O0 -DCOMPILE_DL_EXTENSION1 -I/root/php-7.2.28 -I/root/php-
7.2.28/ext -I/root/php-7.2.28/ext/date/lib -I/root/php-7.2.28/main -I/root/php-7.2.28/TSRM - I/root/php-7.2.28/Zend -DDEBUG=1 -fPIC -c extension1.c -o Debug/extension1.o -MD -MF Debug/extension1.dep
咱们再次去测试下我们新生成的so库文件,看看这次能不能成功。 重复第一次的步骤,把so文件拷贝到/usr/local/php/lib/php/extensions/no-debug-non-zts-20170718,然后重启
php-fpm 看看
![v2-21b97fd0f76adb05ad420042ccfec1ce_b.jpg](http://img-03.proxy.5ce.com/view/image?&type=2&guid=f07af407-3f30-eb11-8da9-e4434bdf6706&url=https://pic3.zhimg.com/v2-21b97fd0f76adb05ad420042ccfec1ce_b.jpg)
这一次,php-fpm 没有给我们提示其他我们不想看到的信息,好,接下来,咱们用php -m 看看有没有加入咱们的扩展
![v2-710bc2f9af1c233910338e20c8b9fa00_b.jpg](http://img-01.proxy.5ce.com/view/image?&type=2&guid=f07af407-3f30-eb11-8da9-e4434bdf6706&url=https://pic1.zhimg.com/v2-710bc2f9af1c233910338e20c8b9fa00_b.jpg)
这一次,我们的扩展库成功加入到了php豪华套餐组合,哈哈哈