Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2011.12.25;
Скачать: CL | DM;

Вниз

Как можно отучить   Найти похожие ветки 

 
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;
Скачать: CL | DM;

Наверх




Память: 0.52 MB
Время: 0.008 c
15-1315308256
Scott Storch
2011-09-06 15:24
2011.12.25
как повысить восприятие английского на слух.


15-1315236394
Заказчик
2011-09-05 19:26
2011.12.25
Одна база vs несколько баз.


15-1315750988
Kerk
2011-09-11 18:23
2011.12.25
Попиарю чуток свое творчество :)


15-1315555359
OW
2011-09-09 12:02
2011.12.25
Вопрос по EurekaLog. Исходный код включить можно?


15-1315427389
Юрий
2011-09-08 00:29
2011.12.25
С днем рождения ! 8 сентября 2011 четверг