Что нового

Объектно-ориентированное программирование в AutoIt

Автор
V

Viktor1703

AutoIT Гуру
Сообщения
1,535
Репутация
413
sims

У меня PB 5.10, да и основной проблемы оно не решает.
 

sims

Осваивающий
Сообщения
184
Репутация
24
Viktor1703 [?]
основной проблемы оно не решает
Какова основная проблема?
Если хотите получить из dll, объект в формате AutoIt, то не думаю что это так просто. Спросите у разработчиков. Может они что-то подскажут.
 
Автор
V

Viktor1703

AutoIT Гуру
Сообщения
1,535
Репутация
413
sims [?]
Какова основная проблема?

Например в некоторых языках нет ObjCreateInterface, а значит такого рода Dll бесполезна, нужно из dll возвращать готовый объект а не указатель на таблицу, если же это не возможно, то не велика потеря...
 

sims

Осваивающий
Сообщения
184
Репутация
24
Вам наверное нужно ActiveX (*.ocx)?
ИМХО преимущества перед обычными dll нет, но требует регистрации в системе, что минус.
 
Автор
V

Viktor1703

AutoIT Гуру
Сообщения
1,535
Репутация
413
sims [?]
ИМХО преимущества перед обычными dll нет, но требует регистрации в системе, что минус.

Вот именно ActiveX я не долюбливаю, в общем с помощью тестов получилось вернуть из dll именно объект, но как вы уже говорили, методов он не видит, нужно создавать интерфейс в AutoIt скрипте, либо писать dll как полагается с обработкой QueryInterface, AddRef, Release, Invoke, GetIDsOfNames и т.д.

Кажется нашёл решение, попробую завтра сделать (точнее сегодня).
 
Автор
V

Viktor1703

AutoIT Гуру
Сообщения
1,535
Репутация
413
Ну вот всё и решилось, обычная dll которая возвращает готовый объект.

AutoIt
Код:
$hObjectDll = DllOpen('class.dll')

$oObj = CreateObject($hObjectDll)

If IsObj($oObj) Then
	
	$pMem = $oObj.AllocateMemory(256)
    $Size = $oObj.MemorySize($pMem)

	$tBuffer = DllStructCreate('byte[' & $Size & ']', $pMem)
	DllStructSetData($tBuffer, 1, 'Hello')
	$tBuffer = 0

	$tBuffer = DllStructCreate('byte[' & $Size & ']', $pMem)
	MsgBox(0, '', BinaryToString(DllStructGetData($tBuffer, 1)))

    $oObj.FreeMemory($pMem)
	$oObj.ReleaseObj()
	$oObj = 0
	
EndIf

DllClose($hObjectDll)

Func CreateObject($hObjectDll)
	Local $oRet = DllCall($hObjectDll, 'idispatch*', 'CreateObject')
    If ((Not @error) And IsArray($oRet) And IsObj($oRet[0])) Then
		Return $oRet[0]
    EndIf
	Return 0
EndFunc


PureBasic
Код:
EnableExplicit 

Enumeration
  #RELEASEOBJ
  #ALLOCATEMEMORY
  #MEMORYSIZE
  #FREEMEMORY
EndEnumeration  

Structure API_OBJ 
  *VTable 
  cntRef.l 
  *own.IUnknown 
EndStructure 

Declare.l API__AllocateMemory(*self, size.l, *result = 0)
Declare.l API__MemorySize(*self, *memid, *result = 0)
Declare API__PokeString(*self, *memid, *string)
Declare API__FreeMemory(*self, *memid)

ProcedureDLL CreateObject() 
  Protected *object.API_OBJ 

  *object = AllocateMemory(SizeOf(API_OBJ)) 
  If *object 
    *object\VTABLE = ?Methods 
    *object\own   = *object 
    *object\own\AddRef() 
    ProcedureReturn *object 
  EndIf 
  ProcedureReturn 0 
EndProcedure 

Procedure.l API__QueryInterface(*self.API_OBJ, *iid.IID, *object.Integer) 
  If CompareMemory(*iid, ?IID_IUnknown, 16) 
    *object\i = *self 
    *self\own\AddRef() 
    ProcedureReturn #S_OK 
  EndIf 
  *Object\i = 0 
  ProcedureReturn #E_NOINTERFACE 
EndProcedure 

Procedure.l API__AddRef(*self.API_OBJ) 
  *self\cntRef + 1 
  ProcedureReturn *self\cntRef 
EndProcedure 

Procedure.l API__Release(*self.API_OBJ) 
  If *self\cntRef > 1 
    *self\cntRef - 1 
    ProcedureReturn *self\cntRef 
  EndIf 
  FreeMemory(*self) 
  ProcedureReturn 0 
EndProcedure 
  
Procedure.l API__GetTypeInfoCount(*self.API_OBJ, *CntTypeInfo.Long) 
  *CntTypeInfo\l = 0 
  ProcedureReturn #S_OK 
EndProcedure 
  
Procedure.l API__GetTypeInfo(*self.API_OBJ, TypeInfo.l, LocalId.l, *ppTypeInfo.Integer) 
  ProcedureReturn #S_OK 
EndProcedure 

Procedure.l API__GetIDsOfNames(*self.API_OBJ, *iid.IID, *Name.String, cntNames.l, lcid.l, *DispId.Long) 
  Select *Name\s 
    Case "ReleaseObj" 
      *DispId\l = #RELEASEOBJ
    Case "AllocateMemory"  
      *DispId\l = #ALLOCATEMEMORY
    Case "MemorySize"
      *DispId\l = #MEMORYSIZE
    Case "FreeMemory"
      *DispId\l = #FREEMEMORY
  EndSelect    
EndProcedure 

Procedure.l API__Invoke(*self.API_OBJ, DispId.l, *iid.IID, lcid.l, Flags.w, *DispParams.DISPPARAMS, *vResult.VARIANT, *ExcepInfo, *ArgErr.Integer)
  Dim vArg.VARIANT(20) 
  
  CopyMemory(*DispParams\rgvarg, @vArg(), 20 * SizeOf(VARIANT)) 

  Select DispId
    Case #RELEASEOBJ
      API__Release(*self)
    Case #ALLOCATEMEMORY
      VariantChangeType_(vArg(0), vArg(0), 0, #VT_I4)
      *vResult\vt = #VT_I4
      *vResult\byref = API__AllocateMemory(*self, vArg(0)\lVal)
    Case #MEMORYSIZE
      VariantChangeType_(vArg(0), vArg(0), 0, #VT_I4)
      *vResult\vt = #VT_I4
      *vResult\lVal = API__MemorySize(*self, vArg(0)\byref)
    Case #FREEMEMORY
      VariantChangeType_(vArg(0), vArg(0), 0, #VT_I4)
      API__FreeMemory(*self, vArg(0)\byref)
  EndSelect
EndProcedure 

Procedure.l API__AllocateMemory(*self.API_OBJ, size.l, *res.Long=0) 
  Define *result = AllocateMemory(size)
  If *res 
    *res\l = *result
  EndIf 
  ProcedureReturn *result 
EndProcedure 

Procedure.l API__MemorySize(*self.API_OBJ, *memid, *res.Long=0)
  Define result.l = 0
  If *memid
    result = MemorySize(*memid)
    If *res 
      *res\l = result
    EndIf 
  EndIf
  ProcedureReturn result
EndProcedure  

Procedure API__FreeMemory(*self.API_OBJ, *memid)
  If *memid
    FreeMemory(*memid)
  EndIf
EndProcedure

DataSection 
  Methods: 
  Data.i @API__QueryInterface() 
  Data.i @API__AddRef() 
  Data.i @API__Release() 
  Data.i @API__GetTypeInfoCount() 
  Data.i @API__GetTypeInfo() 
  Data.i @API__GetIDsOfNames() 
  Data.i @API__Invoke() 
  Data.i @API__AllocateMemory()
  Data.i @API__MemorySize()
  Data.i @API__FreeMemory()
  
  IID_IUnknown: 
  Data.l $00000000 
  Data.w $0000,$0000 
  Data.b $C0,$00,$00,$00,$00,$00,$00,$46 
EndDataSection
 
Автор
V

Viktor1703

AutoIT Гуру
Сообщения
1,535
Репутация
413
sims [?]
Да, это прибавит им работы, но оно того стоит, ведь упростит разработку. Стоит попросить. Возможно что сделают.

Не, не сделают, уже спрашивал на оф. форуме про поддержку пространств имён, мне сказали что AutoIt не объектно - ориентированный и в нём нельзя этого сделать, так же это написано в "что никогда не будет реализовано в AutoIt", так что пролетаем ;D
 

sims

Осваивающий
Сообщения
184
Репутация
24
Viktor1703 [?]
спрашивал на оф. форуме про поддержку пространств имён, мне сказали что AutoIt не объектно - ориентированный и в нём нельзя этого сделать
Как пространства имен связаны с ООП?
Или разробы что-то не правильно поняли, или они реально не в теме и не знают в чем разница. :shok: :scratch:
 

_dron_

Знающий
Сообщения
84
Репутация
8
что вы зацепились за пространство имен есть оно в AutoIt - это локальное и глобальное пространство. ;D
 

sims

Осваивающий
Сообщения
184
Репутация
24
_dron_ [?]
Подразумеваете функции?
Это не совсем то, что имеется в виду. http://ru.wikipedia.org/wiki/Пространство_имён_(программирование)

Учитывая специфику библиотек автоита, данная тема более чем актуальна. Пространства имен позволяют исключить коллизии имен различных объектов и иметь одноименные функции, переменные, массивы и т. д. в одном проекте и глобальные переменные, которые глобальны не для всей программы, а только для текущего пространства.
 

_dron_

Знающий
Сообщения
84
Репутация
8
это был сорказм!
и если честно пространством занимается компилятор преобразовывая обращение вида
Код:
namespace foo {
  int bar;
}
foo::bar = 3

вввввв

Код:
int foo_bar;
foo_bar = 3;

естественно имя другое и не должно совпадать с другими, но этим занимается компилятор (точнее транслятор а уже потом компилятор)
 
Автор
V

Viktor1703

AutoIT Гуру
Сообщения
1,535
Репутация
413
sims [?]
Или разробы что-то не правильно поняли, или они реально не в теме и не знают в чем разница.

Видимо не в теме, потому что мне стали кидать примеры с использованием AutoItObject, хотя этот пример основной проблемы не решает (запретить/разрешить) доступ к функции вне модуля/объекта.
 

_dron_

Знающий
Сообщения
84
Репутация
8
пространство имен - это просто директива упрощающая доступ к переменным например собрать несколько переменных в область а потом обращаться к этой области. в разных областях могут быть переменные с одинаковым именем вот тебе и стали кидать примеры AutoItObject.

этим занимается транслятор вот пример:
код c++
Код:
namespace foo {
  int bar;
};

int main(int argc, char *argv[])
{
    using namespace foo;
    bar = 6;
    return 0;
}

вот после транслятора (gcc.exe -S)
на выходе ассемблер
Код:
.globl __ZN3foo3barE
	.bss
	.align 4
__ZN3foo3barE:
	.space 4
	.def	___main;	.scl	2;	.type	32;	.endef
	.text
	.align 2
.globl _main
	.def	_main;	.scl	2;	.type	32;	.endef
_main:
	pushl	%ebp
	movl	%esp, %ebp
	subl	$8, %esp
	andl	$-16, %esp
	movl	$0, %eax
	addl	$15, %eax
	addl	$15, %eax
	shrl	$4, %eax
	sall	$4, %eax
	movl	%eax, -4(%ebp)
	movl	-4(%ebp), %eax
	call	__alloca
	call	___main
	movl	$6, __ZN3foo3barE
	movl	$0, %eax
	leave
	ret

обратите внимание:
на с++ namespace foo::bar превратилось в __ZN3foo3barE на ассемблере
 
Автор
V

Viktor1703

AutoIT Гуру
Сообщения
1,535
Репутация
413
_dron_

Я понимаю как работают пространства имён и во что превращаются переменные, функции, методы и т.д., я не понимаю почему разработчики думают что для включения поддержки Namespace в AutoIt, он должен быть объектно-ориентированным.
 

_dron_

Знающий
Сообщения
84
Репутация
8
я не понимаю почему разработчики думают что для включения поддержки Namespace в AutoIt, он должен быть объектно-ориентированным.
это часть ООП вроде ну хотя я в c89 не видел примеров с Namespace. только после c++
 
Автор
V

Viktor1703

AutoIT Гуру
Сообщения
1,535
Репутация
413
_dron_

Как я уже говорил, наглядный пример - PureBasic, не ООП, а пространства имён есть.
 

_dron_

Знающий
Сообщения
84
Репутация
8
как нам говорит википедия - пространство имен в PureBasic появилось с версии 5.20 которая вышла 17 сентября 2013 г. то есть этой фичи 5 мес.
хм, это что получается что AutoIt старше PureBasic? (1998 и 1999 последнее)
AutoIt был сделан для автоматизации а не для написания сложных программ!
 
Автор
V

Viktor1703

AutoIT Гуру
Сообщения
1,535
Репутация
413
_dron_ [?]
это что получается что AutoIt старше PureBasic

Ну да, на 9 месяцев старше


AutoIt был сделан для автоматизации а не для написания сложных программ

Но потом он перерос в то, чем он сейчас является и пока мнение о нём не изменится, этот язык не получит достойного признания, им будут пользоваться в рамках хобби или частной компании, может ошибаюсь.
 

sims

Осваивающий
Сообщения
184
Репутация
24
_dron_ [?]
и если честно пространством занимается компилятор преобразовывая обращение вида
Это может делать так же интерпретатор. Есть же пространство имен в интерпретируемых ЯП, таких как Python, PHP и др.

[?]
это часть ООП вроде ну хотя я в c89 не видел примеров с Namespace. только после c++
То что данная фича появилась в одно время с ООП еще не значит что она без ООП существовать не может.
Как раз наоборот. Namespace без ООП прекрасно существует, а вот ООП без Namespace это уже нарушение концепции.
Ничего не мешает реализовать пространство имен даже если ЯП не поддерживает ООП.

[?]
пространство имен в PureBasic появилось с версии 5.20 которая вышла 17 сентября 2013 г. то есть этой фичи 5 мес.
Разробов PB попросили добавить эту фичу и они пошли на встречу. Жаль что разробы автоита не понимают преимуществ. Если переписать библиотеки автоита с учетом разделения на пространства, станет меньше проблем с возможным дублированием функций и переменных.

Viktor1703 [?]
пока мнение о нём не изменится, этот язык не получит достойного признания, им будут пользоваться в рамках хобби или частной компании
Честно говоря не вижу другого применения автоиту кроме автоматизации.
Скорость работы скрипта оставляет желать лучшего. Скрипт по сути никак не защищен и получить исходник можно без проблем. Это не позволяет использовать его для более или менее серьезных проектов.
 
Автор
V

Viktor1703

AutoIT Гуру
Сообщения
1,535
Репутация
413
sims [?]
Честно говоря не вижу другого применения автоиту кроме автоматизации.Скорость работы скрипта оставляет желать лучшего. Скрипт по сути никак не защищен и получить исходник можно без проблем. Это не позволяет использовать его для более или менее серьезных проектов.

Об этом я и говорю, разработчики должны конкретно взяться за него чтобы AutoIt был не то что бы самым популярным, но хотя бы известным и чтобы не было ярлыков "только для автоматизации", синтаксис у него прекрасный, лёгок, а арсенал какой у него, почти каждый месяц появляется новая интересная UDF, Yashied как - то сказал, что у Jon'а мечта сделать из AutoIt полноценный компилятор, но что - то это не видно, а ведь некая часть работы уже сделана, что мешает взять и написать транслятор пусть даже в те же плюсы, а потом компильнуть каким нибудь g++
 
Верх