Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Где в скомпилированном коде хранится GUID интерфейса? / 25 сообщений из 29, страница 1 из 2
12.10.2020, 05:51
    #40007541
Artem.1st
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Где в скомпилированном коде хранится GUID интерфейса?
При объявлении интерфейса программист может явно указать GUID тут же в исходном коде, как бы “подсказка” для компилятора, какое значение сохранить в скомпилированном коде. Это необходимо для связывания с внешними программами(COM-объекты, библиотеки), также это требование операторов(AS и “QI”). Здесь все логично.

Но, мой вопрос касается ситуации, когда интерфейсы работают внутри одной .exe-программы (т.е. не контактируют с внешними программами).

Вопрос: Если GUID явно НЕ указан в исходном коде, то какую “опасность” не сможет предвидеть компилятор (т.е. в скомпилированном коде появится runtime ошибка) ?

Спасибо.

P.S.
название темы - это как пытаюсь найти ответ.
...
Рейтинг: 0 / 0
12.10.2020, 07:05
    #40007550
SOFT FOR YOU
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Где в скомпилированном коде хранится GUID интерфейса?
Artem.1st,

GUID сохраняется в RTTI (смотри модуль System.TypInfo и TObject.GetInterfaceEntry)
Чревато тем, что когда у тебя есть переменная общего типа, например, IInterface, ты не сможешь получить его частный случай
Частный случай находится как раз по GUID
...
Рейтинг: 0 / 0
12.10.2020, 07:11
    #40007552
Artem.1st
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Где в скомпилированном коде хранится GUID интерфейса?
SOFT FOR YOU
GUID сохраняется в RTTI

Понять помог бы самый простой пример: Когда из исходника убираем GUID, а в runtime выскакивает AV.

P.S.
Вопрос в том, чего не хватает компилятору, чтоб самому сориентироваться(по исходному коду) и правильно сгенерить GUID(там, где их программист не указал явно). М.б. требование “однопроходности” ?
...
Рейтинг: 0 / 0
12.10.2020, 07:19
    #40007555
SOFT FOR YOU
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Где в скомпилированном коде хранится GUID интерфейса?
Artem.1st,

А откуда инфа, что такой сценарий получится?
Я пока слабо его представляю
Попробуй поиграться с таким сценарием
Пока я вижу, что компилятор не даёт получить интерфейс без гвида

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
type
  IMyIntf = interface(IInterface)
    // ['{A9795E4B-D739-49FA-84C1-2AC27E543797}']
    procedure DoSome;
  end;

  TMyObj = class(TInterfacedObject, IMyIntf)
    procedure DoSome;
  end;

procedure TMyObj.DoSome;
begin
  Writeln(Self.ClassName);
end;

var
  I: IInterface;
  My: IMyIntf;

begin
  I := TMyObj.Create;
  I.QueryInterface(IInterface{IMyIntf}, My);

  My.DoSome;

  Write('Press Enter to quit');
  Readln;
end.
...
Рейтинг: 0 / 0
12.10.2020, 07:25
    #40007556
Artem.1st
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Где в скомпилированном коде хранится GUID интерфейса?
SOFT FOR YOU
А откуда инфа, что такой сценарий получится?

Нет инфы, это лишь предположение.

Еще предположение:
QI - как оператор (от имени компилятора требует GUID). Нужен другой пример.
...
Рейтинг: 0 / 0
12.10.2020, 07:29
    #40007558
SOFT FOR YOU
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Где в скомпилированном коде хранится GUID интерфейса?
Artem.1st,

Накатал вариант
QueryInterface возвращает результат, но код вызывает AV

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
type
  IMyIntf = interface(IInterface)
    procedure DoSome;
  end;

  IMyIntfEx = interface(IMyIntf)
    procedure DoSomeEx;
  end;

  TMyObj = class(TInterfacedObject, IMyIntf)
    procedure DoSome;
  end;

procedure TMyObj.DoSome;
begin
  Writeln(Self.ClassName);
end;

var
  I: IInterface;
  My: IMyIntfEx;

begin
  I := TMyObj.Create;
  I.QueryInterface(GetTypeData(TypeInfo(IMyIntfEx)).GUID, My);

  Writeln('My = $', IntToHex(NativeInt(My), SizeOf(Pointer) * 2));
  My.DoSomeEx;

  Write('Press Enter to quit');
  Readln;
end.
...
Рейтинг: 0 / 0
12.10.2020, 07:46
    #40007561
Artem.1st
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Где в скомпилированном коде хранится GUID интерфейса?
SOFT FOR YOU

Накатал вариант
QueryInterface возвращает результат, но код вызывает AV

И добавление GUID заставляет этот код работать правильно?
...
Рейтинг: 0 / 0
12.10.2020, 07:50
    #40007562
SOFT FOR YOU
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Где в скомпилированном коде хранится GUID интерфейса?
Artem.1st
И добавление GUID заставляет этот код работать правильно?


Добавление гвида приведёт к тому, что QueryInterface ничего не найдет
Если в коде есть проверка результата QueryInterface - AV не произойдёт

Artem.1st
P.S.
Как окно консоли оставить на экране ....? сворачивается после вылета...


try/except
...
Рейтинг: 0 / 0
12.10.2020, 08:32
    #40007572
Artem.1st
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Где в скомпилированном коде хранится GUID интерфейса?
SOFT FOR YOU
Добавление гвида приведёт к тому, что QueryInterface ничего не найдет
спасибо за ответы.
Но, к сожалению, “Пример” логически неработающий в обоих случаях (задан ли GUID явным способом или это сделал компилятор неявно)
...
Рейтинг: 0 / 0
12.10.2020, 08:55
    #40007574
Artem.1st
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Где в скомпилированном коде хранится GUID интерфейса?
SOFT FOR YOU,
по логике Примера, в этой строке должен вернуться интерфейс:
SOFT FOR YOU
Код: pascal
1.
  I.QueryInterface(GetTypeData(TypeInfo(IMyIntfEx)).GUID, My);


... но, он не вернется. Не спасает даже явное GUID в декларации интерфейса.
"Ухищрения" лишь помогают получить '0' вместо random(AV), т.е. Пример логически не работает.

В любом случае, Спасибо.
...
Рейтинг: 0 / 0
12.10.2020, 09:30
    #40007585
SOFT FOR YOU
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Где в скомпилированном коде хранится GUID интерфейса?
Artem.1st,

Да ладно )

Во-первых, не ясно, чего ты хочешь получить. С чего ты взял, что на практике будет AV не ясно. Тем более на уровне компилятора. На уровне компилятора ты не сможешь взять as для интерфейса без гвида. Даже QueryInterface не сможешь вызвать для интерфейса без гвида

Насчёт как может получиться вышеуказанный пример
Например, если ты разрабатываешь шаблон, где в качестве типа используется интерфейс, соответственно GetTypeKind равен tkInterface, а гвид можно получить из Rtti

Как раз QueryInterface так и принято использовать
Код: pascal
1.
if (QueryInterface(...) = 0) then ...



Может ты не вкурил пример. TMyObj не поддерживает IMyIntfEx, соответственно QueryInterface не должен вернуть ничего, но он возвращает другой интерфейс. Это происходит потому, что GetTypeData(TypeInfo(IMyIntfEx)).GUID для интерфейсов без гвида возвращает нули, что соответствует IInterface. Т.е. запрашиваешь какой-то интерфейс без гвида, а по факту получается IInterface
...
Рейтинг: 0 / 0
12.10.2020, 10:48
    #40007613
alekcvp
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Где в скомпилированном коде хранится GUID интерфейса?
SOFT FOR YOU,

Код: pascal
1.
I.QueryInterface(IInterface{IMyIntf}, My);

Функция QueryInterface объявлена как
Код: pascal
1.
function QueryInterface(const IID: TGUID; out Obj): HResult; stdcall;

Просто при вызове выше компилятор вместо IMyIntf сам подставляет его GUID. Нет GUID - нет интерфейса.
AV тут вообще не при чём.
...
Рейтинг: 0 / 0
12.10.2020, 10:49
    #40007615
SOFT FOR YOU
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Где в скомпилированном коде хранится GUID интерфейса?
alekcvp,

Я в курсе )
...
Рейтинг: 0 / 0
12.10.2020, 11:27
    #40007633
Barlone
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Где в скомпилированном коде хранится GUID интерфейса?
Artem.1st
SOFT FOR YOU,
по логике Примера, в этой строке должен вернуться интерфейс:
SOFT FOR YOU
Код: pascal
1.
  I.QueryInterface(GetTypeData(TypeInfo(IMyIntfEx)).GUID, My);


... но, он не вернется. Не спасает даже явное GUID в декларации интерфейса.
"Ухищрения" лишь помогают получить '0' вместо random(AV), т.е. Пример логически не работает.

В любом случае, Спасибо.
Не генерирует компилятор никаких GUID автоматически. Если вы вместо этой строки напишите
Код: pascal
1.
  writeln(GUIDToString(GetTypeData(TypeInfo(IMyIntfEx)).GUID));

то увидите {00000000-0000-0000-0000-000000000000}
...
Рейтинг: 0 / 0
12.10.2020, 11:58
    #40007653
Artem.1st
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Где в скомпилированном коде хранится GUID интерфейса?
Пост( 22212431 ) получился непонятым. Уже 3 уважаемых собеседника его неверно поняли.
Приношу извинения.
А такой вариант?
...
Рейтинг: 0 / 0
12.10.2020, 11:59
    #40007654
ъъъъъ
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Где в скомпилированном коде хранится GUID интерфейса?
Похоже, монгольский мальчик вернулся.
...
Рейтинг: 0 / 0
12.10.2020, 12:09
    #40007660
SOFT FOR YOU
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Где в скомпилированном коде хранится GUID интерфейса?
Artem.1st,

SOFT FOR YOU
Может ты не вкурил пример. TMyObj не поддерживает IMyIntfEx, соответственно QueryInterface не должен вернуть ничего, но он возвращает другой интерфейс. Это происходит потому, что GetTypeData(TypeInfo(IMyIntfEx)).GUID для интерфейсов без гвида возвращает нули, что соответствует IInterface. Т.е. запрашиваешь какой-то интерфейс без гвида, а по факту получается IInterface
...
Рейтинг: 0 / 0
12.10.2020, 12:12
    #40007661
Artem.1st
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Где в скомпилированном коде хранится GUID интерфейса?
На других IT-форумах “нарушители правил” не набирают 1000+ сообщений.
:-/
...
Рейтинг: 0 / 0
12.10.2020, 12:39
    #40007674
Mixrud
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Где в скомпилированном коде хранится GUID интерфейса?
Тут хранится:

Код: pascal
1.
2.
3.
4.
5.
class function TRTTIExt.GetGuid<T>: TGUID;
begin
  //pTypeInfo(TypeInfo(T)).TypeData.GUID
  Result := TGUID.Create(pTypeInfo(TypeInfo(T)).TypeData.IntfGuid);
end;



Рекомендуется ограничить дженерик как-то так <T: IInterface> в объявлении
...
Рейтинг: 0 / 0
12.10.2020, 12:41
    #40007676
ziv-2014
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Где в скомпилированном коде хранится GUID интерфейса?
Artem.1st,
Интерфейс - это указатель массив методов. У него может быть GUID, а может и не быть.
И тот и другой вариант будет работать.
GUID нужен для COM, т. к. по GUID происходит поиск нужного интерфейса.
В делфи мы создаем указатель на интерфейс при помощи класса, поэтому GUID не нужен.
В некоторых исключениях GUID все же нужен для работы с интерфейсами в Delphi.
Поэтому общим правилом будет GUID добавлять.
...
Рейтинг: 0 / 0
12.10.2020, 12:53
    #40007683
ziv-2014
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Где в скомпилированном коде хранится GUID интерфейса?
ziv-2014
Artem.1st,
Интерфейс - это указатель массив методов. У него может быть GUID, а может и не быть.
И тот и другой вариант будет работать.
GUID нужен для COM, т. к. по GUID происходит поиск нужного интерфейса.
В делфи мы создаем указатель на интерфейс при помощи класса, поэтому GUID не нужен.
В некоторых исключениях GUID все же нужен для работы с интерфейсами в Delphi.
Поэтому общим правилом будет GUID добавлять.

Есть в Rtti TVirtualInterface, TRawVirtualClass которые позволяют создать interface при этом не создавать класс.
...
Рейтинг: 0 / 0
12.10.2020, 13:25
    #40007699
ziv-2014
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Где в скомпилированном коде хранится GUID интерфейса?
Если вы не задаете GUID, то вы не сможете получить корректный интерфейс через QueryInterface.
Цель GUID найти нужный интерфейс через QueryInterface. Если вы не собираетесь этого делать, то можете не задавать GUID.
...
Рейтинг: 0 / 0
12.10.2020, 13:30
    #40007703
alekcvp
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Где в скомпилированном коде хранится GUID интерфейса?
ziv-2014,

Была такая библиотека TForge, так там автор интерфейсы к recrod'ам прикручивал :)
...
Рейтинг: 0 / 0
12.10.2020, 13:31
    #40007704
Мимопроходящий
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Где в скомпилированном коде хранится GUID интерфейса?
12.10.2020 13:30, alekcvp пишет:
> Была такая библиотека TForge, так там автор интерфейсы к recrod'ам прикручивал :)

эммм...
зачем?!
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
12.10.2020, 13:32
    #40007705
X-Cite
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Где в скомпилированном коде хранится GUID интерфейса?
ziv-2014
Если вы не задаете GUID, то вы не сможете получить корректный интерфейс через QueryInterface.
Цель GUID найти нужный интерфейс через QueryInterface. Если вы не собираетесь этого делать, то можете не задавать GUID.


Я написал обертку к QueryInterface и получаю интерфейсы без GUID через TypeInfo
Все интерфейсы можно получать через TypeInfo...

Даже задачу сделал в QC, чтобы они изменил RTL, чтобы из коробки это работало для is/as
...
Рейтинг: 0 / 0
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Где в скомпилированном коде хранится GUID интерфейса? / 25 сообщений из 29, страница 1 из 2
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]