I get the following error when I try to call my Delphi COM object from my 32-bit WPF .NET project in Visual Studio 2019 (var x = new DelphiCOMServiceImplementation();):
Retrieving the COM class factory for component with CLSID {D448873F-EAF7-4F40-8BC7-EF9853E64A0F} failed due to the following error: 80040154 Class not registered (Exception from HRESULT: 0x80040154 (REGDB_E_CLASSNOTREG)).
On the 32-bit Delphi ActiveX project side (I am running Delphi 10.3), my COM interface looks like this:
The TLB's Pascal interface is generated as follows:
interface
uses Winapi.Windows, System.Classes, System.Variants, System.Win.StdVCL, Vcl.Graphics, Vcl.OleServer, Winapi.ActiveX;
// *********************************************************************//
// GUIDS declared in the TypeLibrary. Following prefixes are used:
// Type Libraries : LIBID_xxxx
// CoClasses : CLASS_xxxx
// DISPInterfaces : DIID_xxxx
// Non-DISP interfaces: IID_xxxx
// *********************************************************************//
const
// TypeLibrary Major and minor versions
DelphiCOMServiceMajorVersion = 1;
DelphiCOMServiceMinorVersion = 0;
LIBID_DelphiCOMService: TGUID = '{E999851C-1E08-4C64-B82A-C3A979F96C2F}';
IID_IDelphiCOMService: TGUID = '{D91553DB-A372-4279-AD31-9A1AE0C68F23}';
CLASS_DelphiCOMServiceImplementation: TGUID = '{D448873F-EAF7-4F40-8BC7-EF9853E64A0F}';
type
// *********************************************************************//
// Forward declaration of types defined in TypeLibrary
// *********************************************************************//
IDelphiCOMService = interface;
IDelphiCOMServiceDisp = dispinterface;
// *********************************************************************//
// Declaration of CoClasses defined in Type Library
// (NOTE: Here we map each CoClass to its Default Interface)
// *********************************************************************//
DelphiCOMServiceImplementation = IDelphiCOMService;
// *********************************************************************//
// Interface: IDelphiCOMService
// Flags: (4416) Dual OleAutomation Dispatchable
// GUID: {D91553DB-A372-4279-AD31-9A1AE0C68F23}
// *********************************************************************//
IDelphiCOMService = interface(IDispatch)
['{D91553DB-A372-4279-AD31-9A1AE0C68F23}']
procedure EmbedWPFWindow(Pointer: LongWord; Width: SYSINT; Height: SYSINT); safecall;
procedure WindowResized(Width: SYSINT; Height: SYSINT); safecall;
end;
// *********************************************************************//
// DispIntf: IDelphiCOMServiceDisp
// Flags: (4416) Dual OleAutomation Dispatchable
// GUID: {D91553DB-A372-4279-AD31-9A1AE0C68F23}
// *********************************************************************//
IDelphiCOMServiceDisp = dispinterface
['{D91553DB-A372-4279-AD31-9A1AE0C68F23}']
procedure EmbedWPFWindow(Pointer: LongWord; Width: SYSINT; Height: SYSINT); dispid 201;
procedure WindowResized(Width: SYSINT; Height: SYSINT); dispid 202;
end;
// *********************************************************************//
// The Class CoDelphiCOMServiceImplementation provides a Create and CreateRemote method to
// create instances of the default interface IDelphiCOMService exposed by
// the CoClass DelphiCOMServiceImplementation. The functions are intended to be used by
// clients wishing to automate the CoClass objects exposed by the
// server of this typelibrary.
// *********************************************************************//
CoDelphiCOMServiceImplementation = class
class function Create: IDelphiCOMService;
class function CreateRemote(const MachineName: string): IDelphiCOMService;
end;
implementation
uses System.Win.ComObj;
class function CoDelphiCOMServiceImplementation.Create: IDelphiCOMService;
begin
Result := CreateComObject(CLASS_DelphiCOMServiceImplementation) as IDelphiCOMService;
end;
class function CoDelphiCOMServiceImplementation.CreateRemote(const MachineName: string): IDelphiCOMService;
begin
Result := CreateRemoteComObject(MachineName, CLASS_DelphiCOMServiceImplementation) as IDelphiCOMService;
end;
end.
My Delphi CoClass implementation is as follows (this is the class it can't seem to find as registered, so I am wondering if my implementation is correct or if I missed some detail):
unit DelphiCOMServiceUnit;
interface
uses ComObj, DelphiCOMService_TLB, Winapi.ActiveX, StdVcl;
type
DelphiCOMServiceImplementation = class(TAutoObject, IDelphiCOMService)
public
procedure EmbedWPFWindow(Pointer: LongWord; Width: SYSINT; Height: SYSINT); safecall;
procedure WindowResized(Width: SYSINT; Height: SYSINT); safecall;
end;
implementation
procedure DelphiCOMServiceImplementation.EmbedWPFWindow(Pointer: LongWord; Width: SYSINT; Height: SYSINT); safecall;
begin
end;
procedure DelphiCOMServiceImplementation.WindowResized(Width: SYSINT; Height: SYSINT); safecall;
begin
end;
end.
I have tried both 32-bit and 64-bit versions of regsvr32 without any issues (it always registers successfully):
regsvr32 DelphiCOMService.dll
C:\Windows\SysWOW64\regsvr32.exe DelphiCOMService.dll
I have tried running dumpbin /exports on DelphiCOMService.dll, and it looks okay to me:
Dump of file DelphiCOMService.dll
File Type: DLL
Section contains the following exports for DelphiCOMService.dll
00000000 characteristics 0 time date stamp 0.00 version 1 ordinal base 8 number of functions 8 number of names ordinal hint RVA name 7 0 00101BE0 DllCanUnloadNow 8 1 00101B98 DllGetClassObject 4 2 00101C90 DllInstall 6 3 00101C08 DllRegisterServer 5 4 00101C4C DllUnregisterServer 3 5 00065514 TMethodImplementationIntercept 2 6 00010890 __dbk_fcall_wrapper 1 7 00214640 dbkFCallWrapperAddrSummary
7000 .bss 6000 .data 997000 .debug 1000 .didata 1000 .edata 4000 .idata 2000 .itext 1000 .rdata 30000 .reloc 7000 .rsrc 208000 .text
Could anyone tell me what I can do to get C# to be able to call into my Delphi COM object's function? Did I miss something when I created that unit which houses the DelphiCOMServiceImplementation type, or miss a detail when implementing it, and thus, that causes the CoClass to not be found as a registered object? I tried to find the COM wizards that I keep reading about in my version of Delphi in order to create a class using them and comparing what works to what doesn’t, but I couldn’t find any wizard in my version of Delphi for creating COM classes.






CoClassinterface definition is not correct. Meaning, I think the code in myDelphiCOMServiceUnit(above) is not correct. I manually coded theDelphiCOMServiceImplementationclass in that unit. What is linking that class to COM for consumption? Is it enough to just code a new type like I did with the same name as my CoClass's name? Does the unit name matter? Does it have to exist under a certain namespace, etc.? - AlexandruDllRegisterServer? I never implemented anything like that. - Alexandru