Здравствуйте уважаемые,
Возникла интересная задачка
Для одного из приложений нужно сделать на Delphi свою реализацию объекта WScript. Это тот самый объект, который доступен при выполнении VBScript скриптов на Windows Script Host. Помимо прочего, в объекте WScript есть метод WScript.Echo, который принимает переменный список аргументов
http://msdn.microsoft.com/en-us/library/h8f603s7%28v=VS.85%29.aspx.
И я ни как не могу сообразить, какая сигнатура должна быть у метода Echo в Delphi, чтобы он нормально находился через IDispatch. При имплементации на VisualBasic такой список агументов соответствует ParamArray.
Буду благодарен за подсказку
Здравствуйте, -ras-, Вы писали:
R>Для одного из приложений нужно сделать на Delphi свою реализацию объекта WScript. Это тот самый объект, который доступен при выполнении VBScript скриптов на Windows Script Host. Помимо прочего, в объекте WScript есть метод WScript.Echo, который принимает переменный список аргументов http://msdn.microsoft.com/en-us/library/h8f603s7%28v=VS.85%29.aspx.
R>И я ни как не могу сообразить, какая сигнатура должна быть у метода Echo в Delphi, чтобы он нормально находился через IDispatch. При имплементации на VisualBasic такой список агументов соответствует ParamArray.
Переменное число параметров из Java Script в COMАвтор: Odi$$ey
Дата: 09.12.04
.
Вот спасибо! То что нужно!
Есть пара подводных камней, поэтому приведу развернутое решение — возможно кому-то сэкомномит время:
В классе (потомке TAutoObject) определил метод как
procedure Echo(var args: PSafeArray); safecall;
Для того чтобы метод был распознан как метод с переменным числом аргументов необходимо создать TypeLibrary и прописать для него аттрибут [vararg].
Delphi (как минимум до 2007 включительно) не позволяет [vararg] напрямую, но есть обходной путь:
1) экспортируем TLB в IDL
2) добавляем аттрибут [vararg] к описанию метода
[
id(0x000000C9), vararg
]
HRESULT _stdcall Echo([in] SAFEARRAY(VARIANT) * args );
3) компилируем IDL обратно в TLB с помощью
MIDL /client none /server none /tlb libraryname.tlb /win32 libraryname.idl
4) _заменяем_ существующий tlb-файл в каталоге проекта новым
Дальше — как обычно, собираем и регистрируем automation библиотеку в системе, и вызываем наш метод.
Второй подводный камень — если вам как и мне нужно обойтись без регистрации COM в системе. В этом случае нужно создать TLB, TLB.pas и имлементацию как для обычного AutomationObject, а затем:
1) унаследовать ваш AutomationObject от TAutoIntfObject вместо TAutoObject
2) удалить создание TAutoObjectFactory из блока initialization
3) вручную загружать ITypeLibrary из ресурсов и отдавать ее в конструктор объекта
var
TypeLib : ITypeLib;
begin
...
OleCheck(LoadTypeLib(PWideChar(ParamStr(0)), TypeLib));
obj := TScriptHelper.Create(TypeLib, IScriptHelper);