如何在 Delphi 中调用 .NET Core 6.0 DLL?

发布于 2025-01-12 05:54:47 字数 2860 浏览 0 评论 0原文

初始情况

我之前在.NET Framework中使用了C组件O对象Model (COM)来使用我的C#类Delphi 中的库,如YouTube 教程所示,效果出奇的好。但是,我现在想改用 .NET Core 6。

遵循 Microsoft 的官方教程 "Expose .NET Core 组件到 COM”,我创建了这个接口

using System.Runtime.InteropServices;

[ComVisible(true)]
[Guid(6775d93d-cf14-42b9-83db-425bac0acf4d)]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IServer
{
    public string getHelloWorld();
}

和这个类。

using System.Runtime.InteropServices;

[ComVisible(true)]
[Guid(d62bf794-d29e-4fcd-8637-994490264a93)]
public class Server : IServer
{
    public string getHelloWorld()
    {
        return "Hello World";
    }
}

构建项目后,我执行此命令以向 COM 注册所有公开的 .NET 对象。

regsvr32 MyProjectName.comhost.dll

命令执行成功。我现在尝试在 Delphi 中导入创建的 .dll 文件,就像我之前使用 .NET Framework 编写的类库所做的那样(请参阅 YouTube 教程的时间戳)。但是,Delphi 遇到错误,因为它无法加载类型库。


编辑1:哥斯拉型重大更改

根据官方文档...

与 .NET Framework 不同,.NET Core 或 .NET 5+ 不支持从 .NET 程序集生成 COM 类型库 (TLB)。指南是为 COM 接口的本机声明手动编写 IDL 文件或 C/C++ 标头。如果您决定编写 IDL 文件,则可以使用 Visual C++ SDK 的 MIDL 编译器对其进行编译以生成 TLB。

....NET Core 不支持生成类型库。


编辑2:MIDL编译器

但是,仍然有一种方法可以使用MIDL编译器手动生成TBL文件。正如您可以在官方文档中阅读的那样, MIDL 编译器处理 IDL 文件以生成类型库。话虽如此,我使用 本指南

[
    uuid(a93d03e0-9adf-4a2d-93e3-0ccfc2d8e1a6),
    lcid(0x0409),
    version(1.0),
]
library MyProjectName
{
    importlib("stdole.tlb"); 
    [
        uuid(16292ce5-ccd1-405d-9a70-ace42152bb15),
        oleautomation,
        dual
    ]
    interface IServer: IUnknown {
        HRESULT getHelloWorld([out, string] IServer** string);
    };
};

但是,当我执行以下命令生成 .tlb 文件时,出现错误。

midl myProjectName.idl /tlb myProjectName.tlb

> midl : command line error MIDL1005 : cannot find C preprocessor cl.exe

问题:我在计算机上搜索cl.exe,但找不到任何内容。

问:有人知道如何解决我的问题吗?我非常感谢任何形式的帮助,干杯!

Initial situation

I made use of the Component Object Model (COM) in the .NET Framework before in order to use my C# class library in Delphi as shown in this YouTube tutorial, which worked surprisingly well. However, I now want to use .NET Core 6 instead.

Following the official tutorial from Microsoft "Expose .NET Core components to COM", I created this interface

using System.Runtime.InteropServices;

[ComVisible(true)]
[Guid(6775d93d-cf14-42b9-83db-425bac0acf4d)]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IServer
{
    public string getHelloWorld();
}

and this class.

using System.Runtime.InteropServices;

[ComVisible(true)]
[Guid(d62bf794-d29e-4fcd-8637-994490264a93)]
public class Server : IServer
{
    public string getHelloWorld()
    {
        return "Hello World";
    }
}

After building the project, I executed this command to register all of my exposed .NET objects with COM.

regsvr32 MyProjectName.comhost.dll

The command executed successfully. I now tried to import the created .dll file in Delphi, like I did before with the class libraries written in .NET Framework (See timestamp of YouTube tutorial). However, Delphi runs into an error because it can't load the type library.


Edit 1: Godzilla-type breaking change

According to the official documentation...

Unlike in .NET Framework, there is no support in .NET Core or .NET 5+ for generating a COM Type Library (TLB) from a .NET assembly. The guidance is to either manually write an IDL file or a C/C++ header for the native declarations of the COM interfaces. If you decide to write an IDL file, you can compile it with the Visual C++ SDK's MIDL compiler to produce a TLB.

... there is no support in .NET Core for generating a typelib.


Edit 2: MIDL compiler

However, there is still a way to manually produce a TBL file by using the MIDL compiler. As you can read up in the official documentation, the MIDL compiler processes an IDL file to generate a type library. With that beeing said, I created this IDL file by using this guide.

[
    uuid(a93d03e0-9adf-4a2d-93e3-0ccfc2d8e1a6),
    lcid(0x0409),
    version(1.0),
]
library MyProjectName
{
    importlib("stdole.tlb"); 
    [
        uuid(16292ce5-ccd1-405d-9a70-ace42152bb15),
        oleautomation,
        dual
    ]
    interface IServer: IUnknown {
        HRESULT getHelloWorld([out, string] IServer** string);
    };
};

However, I get an error when I execute the following command to generate the .tlb file.

midl myProjectName.idl /tlb myProjectName.tlb

> midl : command line error MIDL1005 : cannot find C preprocessor cl.exe

Issue: I searched for cl.exe on my Computer but couldn't find anything.

Q.: Does anybody have an idea on how I could solve my problem? I highly appreciate any kind of help, cheers!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

情域 2025-01-19 05:54:47

如果您不介意切换到不同的方法,您可以使用 NativeAOT 从 .Net 编译本机库。您可以在此处找到示例

似乎计划在 .Net 7 中提供,但您已经可以开始使用它与.Net 6。

If you do not mind switching to a different approach, you can compile a native library from .Net using NativeAOT. You can find an example here

It seems to be planned to be available in .Net 7 but you can already start using it with .Net 6.

今天小雨转甜 2025-01-19 05:54:47

使用 MVC 创建 API 并从 Delphi 应用程序调用它不是更容易吗?这样你就可以避免 DLL 的所有问题。

Wouldn't it be easier to create an API using MVC and call that from the Delphi appication. That way you can avoid all the problems with DLL's.

将军与妓 2025-01-19 05:54:47

也许这个工具会对您有所帮助:
https://github.com/dspace-group/dscom

 C:\> dotnet tool install dscom -g

 C:\> dscom tlbexport myassembly.dll

Maybe this tool will help you:
https://github.com/dspace-group/dscom

 C:\> dotnet tool install dscom -g

 C:\> dscom tlbexport myassembly.dll
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文