New face of generic DLL
Dll is a way to share the code with others on the Windows, and Mircosoft gives us three functions to call the functions in the DLL, they are LoadLibrary, FreeLibrary and GetProcAddress.
It is very easy to compile a dll, just follow the wizard.
VC
When you got your DLL, your first job is writing the test code to make sure the DLL works fine. Here's piece of codes
typedef int (*DLLFC)(char* , int *); DLLFC func; HINSTANCE hInst = LoadLibrary("libcode.dll"); if (hInst != NULL) { func= (DLLFC)GetProcAddress(hInst, "encode"); func(src, &len);
As you see, LoadLibrary, open DLL file, and GetProcAddress, map the virtual address to the variable. You can call the function by the variable.
Delphi
You need a little time to call the functions if you're not familiar with Delphi.
procedure TForm1.Button1Click(Sender: TObject); type DllFun=function(str:PChar; len:Pointer):Integer; cdecl; var src:array[0..10240] of Char; func:DllFun; Tlib:Thandle; Tp:TFarProc; rc:Integer; begin len := 0; Tlib := LoadLibrary('libcode.dll'); if Tlib <> 0 then begin try Tp := GetProcAddress(Tlib, PChar('encode')); if Tp = nil then break; func := DllFun(Tp); rc := func(src, @len);
Look, same way as VC
PHP
I tried the w32api dll from php community. php_w32api.dll is out of date. php_ffi.dll can't catch up with the latest version. So I trid to wrap the DLL by myself. First, you need download the lasted binary/source packages, both of them. I downloaded php 5.2.6.
1. unpack them to your work directory: work 2. create the sample dll project. 3. modify the project setting, Project->Settings, or press ALT+F7 a. switch to Win32 Release b. append 'ZEND_DEBUG=0,ZEND_WIN32,PHP_WIN32' to Preprocessror definitions (in C/C++ tab) c: append '/Tc' to Project Options (in C/C++ tab) d: append 'work\php-5.2.6,work\php-5.2.6\main,work\php-5.2.6\regex,work\php-5.2.6\TSRM,work\php-5.2.6\Zend' to Additional include directories (in C/C++ tab) e: append 'php5ts.lib kernel32.lib' to Object/library modules. (in Link tab) f: append 'yourwork\php\dev' to Additional library path (in Link tab) g: change the output filename to php_xxx.dll if you like 5. replace StdAfx.h #include "zend_config.w32.h" #include "php.h" 6. write code
the code
ZEND_FUNCTION(encode); zend_function_entry EncModule_functions[] = { ZEND_FE(encode, NULL) {NULL, NULL, NULL} }; zend_module_entry EncModule_module_entry = { STANDARD_MODULE_HEADER, "Encode Module", EncModule_functions, NULL, NULL, NULL, NULL, NULL, NO_VERSION_YET, STANDARD_MODULE_PROPERTIES }; ZEND_GET_MODULE(EncModule) static ZEND_FUNCTION(encode) { char *str; int str_len; typedef int (*DLLFC)(char* , int *); DLLFC func; char tmp[102400]; HINSTANCE hInst; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &str, &str_len) == FAILURE){ RETURN_LONG(-1); } hInst = LoadLibrary("libcode.dll"); if (hInst == NULL) RETURN_LONG(-1); func= (DLLFC)GetProcAddress(hInst, "encode"); if (func) { func(tmp, &str_len);
7. put php extension module dll to ext directory and put libcode.dll to php home directory 8. edit php.ini, add the module dll name. (refer to the documents in php site) 9. write your php testing code
Notice, you should use FreeLibrary to release the handle before quit.
finished.
Discussion