User Tools

Site Tools


wiki:new_face_of_generic_dll_in_vc_delphi_and_php

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

Enter your comment. Wiki syntax is allowed:
Y Z​ Q᠎ X​ P
 
wiki/new_face_of_generic_dll_in_vc_delphi_and_php.txt · Last modified: 2008/06/25 02:53 by fcmaster