在.NET

当我尝试从Visual Studio 2019(var x = new DelphiCOMServiceImplementation();)的32位WPF .NET项目中调用我的Delphi COM对象时出现以下错误:

  

使用CLSID检索组件的COM类工厂   由于以下原因,{D448873F-EAF7-4F40-8BC7-EF9853E64A0F}失败   错误:80040154未注册类(HRESULT的异常:   0x80040154(REGDB_E_CLASsnOTREG)。

在32位Delphi activeX项目侧(我正在运行Delphi 10.3),我的COM接口如下:

在.NET

在.NET

在.NET

在.NET

在.NET

TLB的Pascal接口生成如下:

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.

我的Delphi CoClass实现如下(这是它似乎找不到已注册的类,因此我想知道我的实现是否正确或是否错过了一些细节):

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.

我尝试了regsvr32的32位和64位版本,没有任何问题(它总是成功注册):

regsvr32 DelphiCOMService.dll

C:\Windows\SysWOW64\regsvr32.exe DelphiCOMService.dll

我尝试在DelphiCOMService.dll上运行 dumpbin / exports ,对我来说没问题:

  

DelphiCOMService.dll文件的转储

     

文件类型:DLL

     

该部分包含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 dbkFCallWrapperAddr
     

摘要

    7000 .bss
    6000 .data
  997000 .debug
    1000 .didata
    1000 .edata
    4000 .idata
    2000 .itext
    1000 .rdata
   30000 .reloc
    7000 .rsrc
  208000 .text

有人可以告诉我如何使C#能够调用我的Delphi COM对象的函数吗?我在创建包含DelphiCOMServiceImplementation类型的单元时是否错过了某些东西,或者在实现它时错过了细节,因此导致CoClass找不到注册对象?我试图找到我在Delphi版本中一直阅读的COM向导,以便使用它们创建一个类,并将有效的与无效的版本进行比较,但是在我的Delphi版本中找不到用于创建的向导COM类。

rus_test 回答:在.NET

this guide之后,在MartynA的帮助下,我遇到了一些问题:

首先,没有什么可以注册我的DelphiCOMServiceImplementation类,即使它具有正确的名称并且实现了正确的接口,该类也需要告诉COM它存在。为此,请添加一个初始化部分:

initialization

TComObjectFactory.Create(ComServer,DelphiCOMServiceImplementation,StringToGUID('{D448873F-EAF7-4F40-8BC7-EF9853E64A0F}'),'DelphiCOMServiceImplementation','',ciMultiInstance,tmApartment);

第二,我相信上面的TComObjectFactory.Create函数仅适用于TComObject派生的类型,因此我将类DelphiCOMServiceImplementation继承为如下(现在它是从{{1}派生的) }):

TComObject

第三,我的界面最初是在* .ridl设计器中使用DelphiCOMServiceImplementation = class(TComObject,IDelphiCOMService) 的。这完全是多余的,我怀疑我需要做一些额外的注册步骤才能使其与此接口配合使用(例如还原回IDispatch并使用TAutoObject,但是我不知道我不打算使用自动化),因此由于我不需要自动化,我将界面切换为TAutoObjectFactory.Create(…)(如下图所示),然后执行了旧的 Save All 刷新实现注册类型库另存为类型库文件 Build (右键单击解决方案), 运行-> ActiveX服务器->注册

enter image description here

现在,它就像魅力一样发挥作用!我的WPF项目完全可以调用我的函数。最后,为了使事情更全面,这里是完整的Delphi CoClass实现:

IUnknown
本文链接:https://www.f2er.com/3089564.html

大家都在问