1

Тема: Использование в PHP dll написанной на Делфи

Добрый день. Перед мной стоит задача импортировать приличное количество кода из Делфи в PHP. Для этого использую DynamicWrapper так как это проще(удобнее) и быстрее чем использовать свои COM объекты. Но не в этом суть. Не получается выполнить функции из dll в PHP, хотя в самом делфи все прекрасно работает.

Код на делфи:

library Project2;

uses  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ComCtrls, Grids, ExtCtrls, Spin;


{$R *.res}
procedure myinc(var c:integer);
begin
  c:=c+1;
end;

procedure mydec(var c:integer);
begin
  c:=c-1;
end;

function mydiv2(c:integer):Integer;
begin
  Result:=c div 2;
end;

exports
myinc name 'myinc',
mydec name 'mydec',
mydiv2 name 'mydiv2';

begin
end.

На выходе имеем dll-ку, все Ок.

PHP:
$com = new COM("DynamicWrapper");
$com->Register("Project2.dll", "mydiv2", "i=l" , "f=s" , "r=l");

Выходит ошибка:
Fatal error: Uncaught exception 'com_exception' with message 'Error [0x80070057] Параметр задан неверно. ' in Z:\home\localhost\www\POS\tstcom.php:12 Stack trace: #0 Z:\home\localhost\www\POS\tstcom.php(12): com->Register('Project2.dll', 'mydiv2', 'i=l', 'f=s', 'r=l') #1 {main}

DynaWrap.dll зарегистрировал, тут все без ошибок. С WinApi функциями работает без проблем. Думал проблема в порядке параметров. Пробовал stdcall в делфи добавлять и с параметром "f=s" экспериментировать(хотя написано, что он игнорируется). В чем загвоздка?

2

Re: Использование в PHP dll написанной на Делфи

Не совсем ясно, речь идёт о DynamicWrapper или DynamicWrapperX?

Если всё-таки о последнем, то "f=" действительно игнорируется. Поддерживаются только два соглашения вызова: stdcall и cdecl.

Судя по ошибке, могу только предположить, что хотя параметры методу Register передаются в переменных типа BSTR, но кодировка строк не UTF-16, поэтому содержимое параметров методу непонятно.

А в других языках — например, VBScript или JScript — не пробовали вашу библиотеку использовать? Там работает?

3

Re: Использование в PHP dll написанной на Делфи

В других языках не пробовал пока что, использую DynamicWrapper.
Но параметры у меня же целого типа INT(long, 4 байта), или речь идет о внутренней работе DynamicWrapper с функциями?

Использовал вот это руководство http://www.script-coding.com/dynwrap.html

4 (изменено: chessman, 2012-03-22 12:29:52)

Re: Использование в PHP dll написанной на Делфи

Выложи Project2.dll

5

Re: Использование в PHP dll написанной на Делфи

Randomav

В других языках не пробовал пока что, использую DynamicWrapper.

А, ну тогда "f=" не игнорируется.

Ошибка у вас происходит ещё на этапе регистрации функции, т.е. неверным является параметр, переданный методу Register, а у него все 5 параметров — строки. До вызова функции из вашей DLL дело даже не доходит.

6 (изменено: Randomav, 2012-03-22 13:12:05)

Re: Использование в PHP dll написанной на Делфи

YMP пишет:

Randomav

В других языках не пробовал пока что, использую DynamicWrapper.

А, ну тогда "f=" не игнорируется.

Ошибка у вас происходит ещё на этапе регистрации функции, т.е. неверным является параметр, переданный методу Register, а у него все 5 параметров — строки. До вызова функции из вашей DLL дело даже не доходит.

Вот оно даже как.
Т.е. мне надо предварительно переводить параметры-строки в UTF-16?

Как на форум файл загрузить не нашел, но в правилах вроде тоже не запрещено.
Файл: http://rghost.ru/37156356

7

Re: Использование в PHP dll написанной на Делфи

На DynamicWrapperX все работает.

Wrap.Register("c:\Temp\Project2.dll", "mydiv2" , "i=l" , "r=l");

8

Re: Использование в PHP dll написанной на Делфи

На VBScript работает и с DynamicWrapper.

9

Re: Использование в PHP dll написанной на Делфи

Randomav

Т.е. мне надо предварительно переводить параметры-строки в UTF-16?

Если они точно не в нём, то да.

10 (изменено: Randomav, 2012-03-22 14:08:28)

Re: Использование в PHP dll написанной на Делфи

Пишу в простом Notepad++ у меня стоит кодировка ANSI, UTF-16 там нет.
Пробую перекодировать так:

function UTF16($str)
{
  //return mb_convert_encoding ($str , "UTF-8", "Windows-1251");
  return iconv('Windows-1251','UTF-16', $str);
}

$com = new COM("DynamicWrapper");
$com->Register("kernel32", "Beep", "i=uu");
$com->Register("kernel32", "GetLastError", "r=u");
$com->Register(UTF16("Project2.dll"), UTF16("mydiv2"), UTF16("i=l") , UTF16("f=s") , UTF16("r=l"));

После перекодировки ошибка не пропала.

И еще вопрос, почему функции из WInAPI (Beep) вызываются без перекодировки?:)

11

Re: Использование в PHP dll написанной на Делфи

А кто же их знает, почему они вызываются? Насчёт кодировки была всего лишь догадка, да и то при условии (не подтвердившемся), что вы использовали DynwrapX. Когда эту ошибку выводит Dynwrap, я не знаю. Попробуйте DynamicWrapperX — что он выдаст.

12 (изменено: Randomav, 2012-03-22 14:41:48)

Re: Использование в PHP dll написанной на Делфи

Скачал архивчик dynwrapx1_00 внутри dll-ка и help.
При регистрации(вашей) COM-dll выдается сообщение "модуль загружен но не удается выполнить вызов DllRegisterServer"
И как следствие Fatal error: Uncaught exception 'com_exception' with message 'Failed to create COM object `DynamicWrapperX':)

П.С. решил проблему установки запустил "от имени администратора"

13

Re: Использование в PHP dll написанной на Делфи

Можно было и для пользователя зарегить, в хелпе описано как.

14

Re: Использование в PHP dll написанной на Делфи

Пробую делать так:
$com = new COM("DynamicWrapperX");
$com->Register("Project2.dll", "mydiv2", "i=l" , "r=l")
и так
$com->Register(UTF16("Project2.dll"), UTF16("mydiv2"), UTF16("i=l") , UTF16("r=l"))

выходит Fatal error: Uncaught exception 'com_exception' with message 'Error [0x80070006] Неверный дескриптор. ' in Z:\home\localhost\www\POS\tstcom.php:18 Stack trace: #0 Z:\home\localhost\www\POS\tstcom.php(18): com->Register('???P?r?o?j?e?c?...', '???m?y?d?i?v?2', '???i?=?l', '???r?=?l') #1

Возможно я неправильно ANSI в UTF-16 перекодирую
iconv('Windows-1251','UTF-16', $str)
пробовал также
iconv('ISO8859-5','UTF-16', $str)

15

Re: Использование в PHP dll написанной на Делфи

А, теперь понятно. Не находит DLL. Где она лежит? Попробуйте полный путь указать. Либо положите её в папку, которая указана в переменной окружения PATH. Апишные DLL находятся без пути, т.к. они в системной папке лежат. Перекодировать не нужно.

16 (изменено: Randomav, 2012-03-22 15:55:09)

Re: Использование в PHP dll написанной на Делфи

Действительно все заработало, без вас бы никак:)
Спасибо большое за помощь!!!

17

Re: Использование в PHP dll написанной на Делфи

Randomav, код на форуме оформляется тэгом «code».