Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Прочее";
Текущий архив: 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
11-1236511074
Jon
2009-03-08 14:17
2011.12.25
CreateRestrictedToken


2-1315895287
KIR@PRO
2011-09-13 10:28
2011.12.25
TComboBox vs PStrings


15-1314986696
Virgo_Style
2011-09-02 22:04
2011.12.25
программирование IncDay-style


15-1315548799
user1987
2011-09-09 10:13
2011.12.25
Часы на рабочем столе


2-1316076960
pk
2011-09-15 12:56
2011.12.25
TpFibDataSet передать значение параметру





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский