Форум: "Прочее";
Текущий архив: 2011.12.25;
Скачать: [xml.tar.bz2];
ВнизКак можно отучить Найти похожие ветки
← →
Dimka Maslov © (2011-09-08 22:08) [0]Delphi неявно преобразовывать
function F: IInterface
вprocedure F(out Obj: IInterface)
?
← →
han_malign (2011-09-09 10:58) [1]Никак, это специальное семантическое ограничение.
До D7 включительно - function "честный"... - и приводит к утечке счетчика ссылок...
Еслиout
гарантирует сохранение и последующую очистку ссылки, то куда попадет и как будет преобразованEAX
- неизвестно...
← →
han_malign (2011-09-09 11:25) [2]Точнее, не так - в D7 функция тоже нечестная...
Но(!) - применение функциональной семантики приводит к созданию дополнительной неявной ссылки на интерфейс и нормальная(-вроде бы-)атомарная конструкция:begin
CoInitialize(nil)
obj.F.someMethod()
CoUninitialize();
end;
и дажеbegin
CoInitialize(nil)
intfRef:= obj.F;
intfRef.someMethod()
intfRef:= nil;
CoUninitialize();
end;
- приводит к вылету, т.к. неявная ссылка очищается в неявной finally секции(после CoUninitialize())...
Поэтому лучше использовать явнуюout
семантику...
З.Ы. А вот с классическими dispinterface на вариантах - приходится выносить СoI/U в дополнительную внешнюю обертку...
← →
han_malign (2011-09-09 11:44) [3]реализация "честной" функции невозможна из-за неоднозначности контракта функции и интерфейсной "магии" - где счетчик увеличивать...
А если сильно надо - то только явное приведение типа Pointer <=> Interface, когда - если что - сам дурак...
← →
Dimka Maslov © (2011-09-09 12:48) [4]Дело в том, что интерфейсы (их много) реализованы в сишной dll и указатели на них передаются именно как результат функции - через eax. Сейчас всё сделано так, что функции в дельфе объявлены как возвращающие Pointer (что соответственно показывается в подсказке), но хочется видеть именно имя интерфейса.
← →
Дмитрий С © (2011-09-09 14:19) [5]как вариант можно обертки сделать.
function _xxx(...): pointer;
function xxx(...):ISomeInterface;inline;begin Result := ISomeInterface(_xxx(...)); end;
← →
Омлет © (2011-09-09 14:22) [6]> ISomeInterface(_xxx(...));
Нельзя так, там переменную надо.
← →
_oxffff (2011-09-09 15:20) [7]
> Dimka Maslov © (08.09.11 22:08)
> Delphi неявно преобразовывать
> function F: IInterface
> в
> procedure F(out Obj: IInterface)
> ?
Они практически эквивалентны.
За исключением явных очисток.
← →
_oxffff (2011-09-09 15:30) [8]TStuff=procedure (out r:iunknown);
function abc:iunknown;
begin
result:=Tinterfacedobject.create;
end;
procedure TForm1.FormCreate(Sender: TObject);
var Stuff:TStuff;
r:iunknown;
begin
stuff:=@abc;
stuff(r);
r:=nil;
end;
← →
han_malign (2011-09-09 15:48) [9]
> Нельзя так, там переменную надо.
pointer(Result):= _xxx(...)
по стандарту - счетчик ссылок увеличивает метод возвращающий интерфейс(С-dll), соответственно нужно как раз избежать лишнего AddRef...
← →
_oxffff (2011-09-09 16:03) [10]Обретение счаться
TconstParamProc<T>=reference to procedure(const param:T);
TForm1 = class(TForm)
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
procedure WrapPointer<T>(p:pointer;proc:TconstParamProc<T>);
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
type
TStuff=procedure (out r:iunknown);
function abc:pointer;
begin
result:=pointer(Iunknown(Tinterfacedobject.create));
end;
procedure TForm1.FormCreate(Sender: TObject);
var Stuff:TStuff;
r:iunknown;
begin
WrapPointer<Iunknown>(abc,procedure (const p:Iunknown)
var a:iunknown;
begin
//Однако думай, что делаешь всегда!!!!!!!!!!
a:=p;
a:=nil; //<-by by object
/////////////////////////////////////////////////////
end);
end;
procedure TForm1.WrapPointer<T>(p: pointer; proc: TconstParamProc<T>);
begin
proc(T((@p)^));
end;
end.
← →
_oxffff (2011-09-09 16:18) [11]
> _oxffff (09.09.11 16:03) [10]
К сожалению вывод типов в Delphi работает слабо.
Поэтому логически корректным является вызов
WrapPointer(abc, procedure (const p:Iunknown)
....
Но он не работает в виду ограничений компилятора.
← →
Дмитрий С © (2011-09-09 16:39) [12]
> _oxffff (09.09.11 16:03) [10]
Как обычно простое решение:)
Так автор хотел, чтобы IDE тип правильно отображал в подсказках, неужели это поможет?
← →
_oxffff (2011-09-09 16:43) [13]
> Дмитрий С © (09.09.11 16:39) [12]
Автор хотел, чтобы семантика интерфейсов не вступала в действие.
Хотя есть решение проще
iunknown(abc())
← →
_oxffff (2011-09-09 16:43) [14]
> Хотя есть решение проще
Та ему же надо неявно. :)))))))))))))))))
← →
Dimka Maslov © (2011-09-09 17:55) [15]
> Они практически эквивалентны.
> За исключением явных очисток.
В Delphi - да. И в случае с функциями, возвращающими запись, такое приведение очень даже полезно. Но в С++ в случае работы с интерфейсами это две большие разности:IUnknown F()
иvoid F(IUnknown** Obj)
Поскольку Си не заморачиваются с неявными вызовами AddRef и Release, там это всё прекрасно работает. Но когда потребовалось взаимодействие между модулями, написанными на сях и дельфях...
> Дмитрий С © (09.09.11 16:39) [12]
Автор хотел, чтобы написанное сразу работало так, как написано, а не так кто-то там считает нужным. А как работать с приведением типов и счётчиком ссылок он знает. Вот только метод борьбы отрицательным образом воздействует на подсказки.
← →
oxffff © (2011-09-09 23:16) [16]
> Но в С++ в случае работы с интерфейсами это две большие
> разности:
> IUnknown F()
> и
> void F(IUnknown** Obj)
>
> Поскольку Си не заморачиваются с неявными вызовами AddRef
> и Release, там это всё прекрасно работает.
То есть в С++ это две большие разницы.
А в С это все прекрасно работает.
Даже не знаю.
← →
oxffff © (2011-09-09 23:17) [17]
> А как работать с приведением типов и счётчиком ссылок он
> знает.
Тогда зачем топик?
← →
oxffff © (2011-09-09 23:21) [18]
> Вот только метод борьбы отрицательным образом воздействует
> на подсказки.
О каких подсказках речь?
Если . и "ctrl+space", то все работает.
← →
Dimka Maslov © (2011-09-10 18:59) [19]
> Тогда зачем топик?
Не зря же он в "Прочем". Ну а кроме того, вдруг есть какое-то другое решение.
> О каких подсказках речь?
О всплывающих. Но раз объявлено Pointer, то там показывается Pointer...
← →
oxffff © (2011-09-10 19:16) [20]
> Dimka Maslov © (10.09.11 18:59) [19]
Ты [10] внимательно смотрел? Там нет указателя, и семантика копирования не отрабатывает. И подсказка работает правильно.
← →
Dimka Maslov © (2011-09-10 20:03) [21]
>
> Ты [10] внимательно смотрел?
У меня дельфя старая
← →
знайка (2011-09-11 01:23) [22]
> У меня дельфя старая
обновить, не?
← →
Dimka Maslov © (2011-09-11 17:56) [23]
> обновить, не?
А кто мне денег даст? Из своего кармана что-ли? Нет, есть отдельные личности, приобретающие себе за свой счёт на работу компьютер, но я не из их числа.
Страницы: 1 вся ветка
Форум: "Прочее";
Текущий архив: 2011.12.25;
Скачать: [xml.tar.bz2];
Память: 0.5 MB
Время: 0.003 c