use dispInterface in Delphi with no classid

2019-07-20 01:45发布

I've imported a type library into Delphi XE2 that has many dispinterfaces. Most of them have had an autocreated coclass and corresponding delphi T interface automatically created.

However, some of the dispinterfaces that I need to work with have no classid; I've tried every example that I could find on the net to utilize the dispinterface(s) in question. Here's what the interface looks like:

DIID_ITableListener: TGUID = '{83D42EA5-2C18-46EB-823B-262D62DF8CF1}';
... 
ITableListener = dispinterface;
...
// *********************************************************************//
// DispIntf:  ITableListener
// Flags:     (4096) Dispatchable
// GUID:      {83D42EA5-2C18-46EB-823B-262D62DF8CF1}
// *********************************************************************//
ITableListener = dispinterface
  ['{83D42EA5-2C18-46EB-823B-262D62DF8CF1}']
  procedure Added(const rowID: WideString; const rowDataObj: IRow); dispid 1610743809;
  procedure Changed(const rowID: WideString; const rowDataObj: IRow); dispid 1610743810;
  procedure Deleted(const rowID: WideString; const rowDataObj: IRow); dispid 1610743811;
  procedure StatusChanged(status: TableStatus); dispid 1610743812;
end;

Here's an example from another interface in the type library wrapper that uses this dispinterface:

procedure subscribeUpdate(updateType: TableUpdateType; const listenerObj: ITableListener);

Here's a VB.NET example that is provided that explains how the dispinterface is supposed to be used:

' If you want to use methods of the ITableListener interface, you must create a 
' class that+ implements the interface. For example,

public class TableListener implements ITableListener { }

' In your application you must create an instance of the class that implements  
' the interface. For example,

TableListener tableListener = new TableListener();

With no ClassID how do I implement this in Delphi? How do I do an instantiation? I thought it would have something to do with implementing an IDispatch interface descendant, but again without a ClassID I couldn't find a way to make this work.

Help!

Thanks.

标签: delphi com
2条回答
Summer. ? 凉城
2楼-- · 2019-07-20 02:00

This issue is solved. Please see Troubleshooting COM error "The parameter is incorrect".

Many thanks to @EricBrown and @RemyLebeau for their assistance.

查看更多
我欲成王,谁敢阻挡
3楼-- · 2019-07-20 02:13

So I went through the sample provided in the link, and substituted your interfaces for the interfaces in the link, and came up with this:

ITableListener = dispinterface
  ['{83D42EA5-2C18-46EB-823B-262D62DF8CF1}']
  procedure Added(const rowID: WideString; const rowDataObj: IRow); dispid 1610743809;
  procedure Changed(const rowID: WideString; const rowDataObj: IRow); dispid 1610743810;
  procedure Deleted(const rowID: WideString; const rowDataObj: IRow); dispid 1610743811;
  procedure StatusChanged(status: TableStatus); dispid 1610743812;
end;

IMyTableListener = interface(IDispatch)
  ['{INSERT ARBITRARY GUID HERE}']
  procedure Added(const rowID: WideString; const rowDataObj: IRow); 
  procedure Changed(const rowID: WideString; const rowDataObj: IRow); 
  procedure Deleted(const rowID: WideString; const rowDataObj: IRow);
  procedure StatusChanged(status: TableStatus);
end;


TMyTableListener = class (TAutoObject, IMyTableListener)
public
  procedure Added(const rowID: WideString; const rowDataObj: IRow); 
  procedure Changed(const rowID: WideString; const rowDataObj: IRow); 
  procedure Deleted(const rowID: WideString; const rowDataObj: IRow);
  procedure StatusChanged(status: TableStatus);
end;

{ ... }
var
Disp: IDispatch;
Dispint: ITableListener;
{ ... }
// this may require that TMyTableListener is registered...
Disp := CreateComObject(TMyTableListener) as IDispatch;
// alternatively, try this (not sure about syntax):
Disp := new TMyTableListener as IDispatch;
Disp.AddRef();   // in C++, at least, creating the class via new() results in a 0 refcount, so you need to AddRef() so that releasing the object destroys the object appropriately...
Dispint := ITableListener(Disp);
subscribeUpdate(updateType, Dispint);
{ ... }
查看更多
登录 后发表回答