Вопрос о присвоении GUID интерфейсу

Я написал этот код в Delphi XE, который назначает GUID интерфейса из GUID const. код компилируется нормально, но я хочу знать, действительно ли это объявление?

const
  IID_IFoo: TGUID = '{00000000-6666-6666-6666-666666666666}';
type
  IFoo = interface(IDispatch)
    [IID_IFoo]
    //properties
    //methods
  end;

person Salvador    schedule 14.07.2011    source источник


Ответы (2)


Вы можете сделать это, но вопрос в том, зачем вам это нужно?

Если вы хотите ссылаться на GUID интерфейса, а не на имя интерфейса, то, если этот интерфейс имеет связанный IID (GUID), вы можете использовать имя интерфейса там, где ожидается TGUID:

type
  IFoo = interface(IDispatch)
    ['{00000000-6666-6666-6666-666666666666}']
    //properties
    //methods
  end;

// meanwhile, elsewhere in the project...

  sFooIID := GUIDToString(IFoo);

Это менее «шумное» объявление интерфейса, позволяющее избежать возможности объявить/сослаться на константу IID, которая на самом деле не связана с интерфейсом, которым вы ее считаете (или которая вообще не связана с этим IID). ).

const
  IID_Foo = '{00000000-6666-6666-6666-666666666666}';
  IID_Bar = '{00000000-6666-6666-6666-777777777777}';

type
  IFoo = interface(IDispatch)
    [IID_Bar]    // WHOOPS!
    :
  end;

  IBar = interface(IDispatch)
    // WHOOPS again!!
    :
  end;


// Meanwhile, elsewhere in the project

sBarID := GUIDToString(IID_Bar);   // Works, but is the IID of IFoo, not IBar
sFooID := GUIDToString(IID_Foo);   // Works, but is an IID not associated with any interface

Использование самого интерфейса как интерфейса и IID вместо отдельного объявления const устраняет вероятность этих ошибок.

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

// Cannot make the mistake of using an interface as a GUID if it has no IID at all

sBarID := GUIDToString(IBar);   // Does not compile - IBar has no IID


// But if it's the wrong IID then you get results that are "correct" but not expected:

a := GUIDToString(IFoo);
b := GUIDToString(IID_Foo);

  a <> b
person Deltics    schedule 15.07.2011
comment
Я не вижу опасности, которую вы представляете, как серьезную, но я думаю, что более идиоматично просто вставлять IID в качестве буквального. - person Warren P; 15.07.2011
comment
Чаще всего вас подстерегают опасности, которых вы не видите. ;) (но да, вероятно, более редкие опасности, чем реальные высокие риски - все равно, зачем вводить возможность этих опасностей, когда в этом нет необходимости?) - person Deltics; 15.07.2011
comment
@Deltics Одной из причин объявления константы GUID отдельно от интерфейса является обходной путь для Delphi, не позволяющий объявлять константу типа интерфейса. См. эти вопросы и ответы. - person Disillusioned; 07.01.2015
comment
@Craig - да, но также должна быть причина / необходимость объявления таких констант. Эти вопросы и ответы начинаются с предположения, что требуется массив TGUID без установления необходимости. Нет информации, определяющей проблему, для решения которой предназначен такой массив. Без этой исходной проблемы еще предстоит установить, что константа GUID необходима даже в этом случае, кроме того, просто потому, что это то, чего хочет OP с самого начала. - person Deltics; 22.01.2015