天天看點

C 編寫動态連結庫PHP DLL

建立-》工程-》win32 dynamic link library->一個簡單的dll工程

隻有在函數前标注:extern   "c"   _declspec(dllexport) 的函數才能被其他的程式通過 dll 的方式調用

C 編寫動态連結庫PHP DLL

extern "c" _declspec(dllexport) int add(int i1,int i2){  

    return i1+i2;  

}  

(1) 靜态連結聲明:

C 編寫動态連結庫PHP DLL

#pragma comment(lib, "dll1.lib")  

extern   "c"   _declspec(dllexport) int add(int i1,int i2);  

 然後就可以像調用普通函數一樣調用了。如果dll中函數很多的話,一般都是由dll開發者開發好.h檔案,把函數的聲明都寫好,然後供其他人調用,隻要include就好了。

(2) 動态連結:

//有 __cdecl __stdcall 等不同的調用約定,也就是參數的壓棧順序等,暫時不用關心,隻要保證調用的時候和 dll 中的調用約定一樣就可以。

聲明函數指針 typedef int(__cdecl*  functionadd)(int,int);

C 編寫動态連結庫PHP DLL

#include "stdafx.h"  

typedef int(__cdecl*  functionadd)(int,int);  

hmodule   hmodule;   //申明句柄  

functionadd   add;   //申明指針  

hmodule   =   loadlibrary("dll1.dll");//調試時hmodule為0x10000000     

if(null==hmodule){  

  //error.  

add   =(functionadd)getprocaddress(hmodule,"add");     

if(null==add){  

  //error  

int r = add(1,1);    

freelibrary(hmodule);  //釋放句柄  

靜态連結和動态連結的差別:靜态連結在程式啟動的時候就會去檢查dll是否存在,如果不存在在啟動的時候就會報錯,程式無法啟動;動态連結是在運作到的時候才會去檢查是否存在,而且可以由程式員決定在dll不存在的時候判斷邏輯。

要區分靜态庫、動态庫。靜态調用dll和動态調用dll。

3、 插件機制。

将你程式設計中經常用到的重複性代碼封裝成dll ,當程式啟動時加載你新增的dll使其具備新的功能,如php的ext dll

前提php擴充骨架已經ok

1、php源碼包和windows下的二進制包,以及安裝visual c++,并把microsoft visual studio\common\msdev98\bin的絕對路徑添加到windows環境變量

2、解壓源碼包到d:\php_src

3、進入d:\php_src\ext源碼包目錄,複制skeleton檔案夾,并重命名為要開發擴充的名字,本例為“linvo”

4、把二進制包中dev目錄下的php5ts.lib檔案,拷入建立的linvo目錄

5、重命名php_skeleton.h為php_linvo.h,skeleton.c為linvo.c,skeleton.dsp為linvo.dsp,編輯linvo目錄中的php_linvo.h、linvo.c、linvo.dsp這三個檔案,替換内容中所有extname為linvo,extname為linvo。(嚴格區分大小寫 )

6、編輯php_linvo.h檔案(頭檔案)

在php_function(confirm_linvo_compiled);下面編寫php_function(hello);聲明一個hello函數

7、編輯linvo.c檔案(主檔案)

在php_fe(confirm_linvo_compiled,    null)下面編寫

php_fe(hello,    null)

這是函數入口,下面該寫函數主體了

找到php_function(confirm_linvo_compiled)函數,該函數是測試函數,在該函數後面新寫一個函數

C 編寫動态連結庫PHP DLL

php_function(hello){  

    char *arg = null;  

    int arg_len, len;  

    char *strg;  

    if (zend_parse_parameters(zend_num_args() tsrmls_cc, "s", &arg, &arg_len) == failure) {  

        return;  

    }  

    len = spprintf(&strg, 0, "hello,%s", arg);  

    return_stringl(strg, len, 0);  

編譯:

8、運作cmd指令行,進入d:\php_src\ext\linvo目錄

9、輸入 msdev linvo.dsp /make "linvo - win32 release_ts"

10、如果沒有錯誤,則在php_src目錄下會生成一個release_ts檔案夾 ,裡面就是編譯好的php_linvo.dll擴充

使用:

11、将其拷入運作環境中的php擴充目錄ext

12、編輯php.ini添加extension=php_linvo.dll,重新開機apache

13、在php檔案中執行如下語句

echo hello('linvo');

将輸出

hello,linvo

14、通過echo phpinfo();也可看到擴充已加載的資訊

通過vc6打開項目空間檔案編譯dll,此時會php_stream_transport.h報錯 

d:\php_src\main\streams\php_stream_transport.h需要通過添加typedef int socklen_t;到檔案中,便可通過編譯