You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

未注册C# COM组件时Delphi调用报错“CLASS未注册”,求免注册方案

问题

未注册C# COM组件时,Delphi无法调用该组件并报错“CLASS is not registered”。

我用C#写了一个COM DLL,在Delphi 10里作为COM对象调用,注册DLL后能正常运行,但我想实现无需注册就能使用该组件,请问该怎么做?

我的C#代码

Assembly.cs中已设置ComVisible属性为true:

[assembly: ComVisible(true)]

组件代码:

using System;
using System.Runtime.InteropServices;
    
namespace ComCalculator
{
    [ComVisible(true)]
    [Guid("c0a3a815-fade-4fb3-9c75-f6eff1851e23")]
    public interface ICalculator
    {
        int Add(int a, int b);
    }

    [ComVisible(true)]
    [ClassInterface(ClassInterfaceType.None)]
    [Guid("427754c1-c975-4099-9ff7-df788281d3a8")]
    public class Calculator : ICalculator
    {
        public int Add(int a, int b)
        {
            return a + b;
        }
    }
}

我的Delphi代码

unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, ComObj, ComCalculator_TLB;

type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure FormCreate(Sender: TObject);
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
    comObject: ICalculator;
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var
  A, B, Result: Integer;
begin
  A := 10;
  B := 5;
  Result := comObject.Add(A, B);
  ShowMessage('The result is: ' + IntToStr(Result));
end;


procedure TForm1.FormCreate(Sender: TObject);
begin
  comObject := CoCalculator.Create;
end;

end.

解决方案

要实现无需注册就能让Delphi调用C# COM组件,有以下几种可行方案:

方案1:使用RegFree COM(免注册COM)

这是Windows官方支持的免注册方式,通过应用程序清单文件描述COM组件信息,替代注册表的作用。

步骤1:生成C#组件的清单文件

  1. 编译C#项目时,临时勾选“为COM互操作注册”(生成必要类型信息后可取消)。
  2. 使用Windows SDK工具mt.exe生成组件清单:
    mt.exe -tlb:ComCalculator.tlb -dll:ComCalculator.dll -out:ComCalculator.manifest
    
    生成的文件会包含组件的CLSID、接口ID等关键信息。

步骤2:创建Delphi应用的清单文件

在Delphi项目根目录创建YourDelphiApp.exe.manifest文件,内容示例如下(替换对应信息):

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
  <assemblyIdentity type="win32" name="YourDelphiApp" version="1.0.0.0" />
  <dependency>
    <dependentAssembly>
      <assemblyIdentity type="win32" name="ComCalculator" version="1.0.0.0" publicKeyToken="你的组件公钥令牌" />
    </dependentAssembly>
  </dependency>
  <file name="ComCalculator.dll">
    <comClass clsid="{427754c1-c975-4099-9ff7-df788281d3a8}" description="ComCalculator.Calculator" />
    <comInterfaceExternalProxyStub iid="{c0a3a815-fade-4fb3-9c75-f6eff1851e23}" name="ICalculator" proxyStubClsid32="{00020424-0000-0000-C000-000000000046}" />
  </file>
</assembly>
  • 公钥令牌可通过sn.exe -T ComCalculator.dll命令获取。
  • 确保ComCalculator.dll与Delphi exe在同一目录。

步骤3:配置Delphi项目

将清单文件与exe放在同一目录,或在Delphi项目设置中嵌入该清单。

方案2:通过Unmanaged Exports直接导出非托管函数

绕开COM规范,用第三方工具直接从C# DLL导出函数,让Delphi直接调用。

步骤1:C#项目配置

  1. 安装UnmanagedExports NuGet包。
  2. 修改C#代码,移除COM相关属性,导出函数:
    using RGiesecke.DllExport;
    using System.Runtime.InteropServices;
    
    namespace ComCalculator
    {
        public class Calculator
        {
            [DllExport("Add", CallingConvention = CallingConvention.StdCall)]
            public static int Add(int a, int b)
            {
                return a + b;
            }
        }
    }
    
    编译生成普通.NET DLL。

步骤2:修改Delphi代码

直接调用导出的函数,无需COM对象:

unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
    function Add(a, b: Integer): Integer; stdcall; external 'ComCalculator.dll';
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var
  A, B, Result: Integer;
begin
  A := 10;
  B := 5;
  Result := Add(A, B);
  ShowMessage('The result is: ' + IntToStr(Result));
end;

end.

确保ComCalculator.dll与Delphi exe在同一目录。

方案3:COM+应用程序隔离(不推荐)

通过COM+创建应用程序包部署组件,无需系统注册表注册,但配置复杂度高,仅适合大型组件场景。


内容的提问来源于stack exchange,提问作者Santosh Vishwakarma

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.18 20:05:29