创建一个可以使用 stdcall 在 Delphi 应用程序中导入的 C# DLL - 可能吗?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1063151/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 07:20:10  来源:igfitidea点击:

Create a C# DLL That Can Be Imported in a Delphi App Using stdcall - Possible?

c#delphidelphi-2007stdcall

提问by Dave

I have a program that I need to create a DLL for, hopefully in C#. The program is written in Delphi and I have an interface file to code to. The interface uses the stdcall calling convention.

我有一个程序,我需要为其创建一个 DLL,希望是在 C# 中。该程序是用 Delphi 编写的,我有一个要编码的接口文件。该接口使用 stdcall 调用约定。

Is it possible to create a C# DLL that conforms to the interface and can be used in the Delphi application?

是否可以创建一个符合接口的C#DLL,可以在Delphi应用程序中使用?

Is there some sample code that demonstrates how to code the C# DLL to a stdcall interface method?

是否有一些示例代码演示了如何将 C# DLL 编码为 stdcall 接口方法?

回答by Steve

Have a look at Hydra

看看九头蛇

回答by Henk Holterman

I'm quite sure this can not be done directly. You'll have to either write a layer in C++/CLI or expose the C# code as an ActiveX interface. But that second option may not meet your interface.

我很确定这不能直接完成。您必须在 C++/CLI 中编写一个层,或者将 C# 代码公开为 ActiveX 接口。但是第二个选项可能不符合您的界面。

回答by Gregory Higley

This is not directly possible. C# is managed code. This means that it requires a very specific runtime environment in order to function, an environment which Delphi could not directly provide to it. It is not like C where you simply find the address and calling convention of the function and call it.

这不是直接可能的。C# 是托管代码。这意味着它需要一个非常特定的运行时环境才能运行,而 Delphi 无法直接提供给它的环境。它不像 C 那样您只需找到函数的地址和调用约定并调用它。

However, it is possible to host the Common Language Runtime inside of a Delphi application (or any other Windows application). I have no idea how to do this. I just know that it's possible. (It's quite likely that's what this 'Hydra' that Steve mentioned will do.)

但是,可以在 Delphi 应用程序(或任何其他 Windows 应用程序)中托管公共语言运行时。我不知道该怎么做。我只知道这是可能的。(很可能这就是史蒂夫提到的这个“九头蛇”会做的。)

回答by devio

You need to make the assembly (=C# DLL) accessible to COM, which is called Interop.

您需要使 COM 可以访问程序集(=C# DLL),这称为 Interop。

See MSDN articles Assembly to Type Library Conversionand Packaging an Assembly for COMwhich describe the technical background and the utilities to perform the required operations.

请参阅 MSDN 文章“程序集到类型库转换”和“为 COM 打包程序集”,其中描述了技术背景和执行所需操作的实用程序。

回答by Cobus Kruger

This is not possible in pure C#, but this is an articlethat shows how to add an unmanaged export table to your C# library, which can then be used in any other language. Note that the hordes of references to Blitz should not put you off - they relate to the author's own context and have nothing to do with the basic concept and how it works.

这在纯 C# 中是不可能的,但这篇文章展示了如何将非托管导出表添加到 C# 库中,然后可以在任何其他语言中使用它。请注意,对 Blitz 的大量引用不应该让您失望——它们与作者自己的上下文有关,与基本概念及其工作原理无关。

There is also a section in Brian Long's one conference paper. In a twist that you could see as somewhat ironic, Delphi.Net actually supported unmanaged exports directly despite C# not doing so. I have no idea if this is true of Delphi Prism as well.

Brian Long 的一篇会议论文中也有一节。有点讽刺的是,Delphi.Net 实际上直接支持非托管导出,尽管 C# 没有这样做。我不知道 Delphi Prism 是否也是如此。

回答by Bruce McGee

Out of curiosity, why are you hoping to write a .dll that's intended to be used from a native application in C#?

出于好奇,您为什么希望编写一个打算在 C# 中的本机应用程序中使用的 .dll?

Managed C++, Delphi for .Net and now Delphi Prism all support this out of the box using unmanaged exports. By design, C# and VB.net don't. Not sure why. But as Cobus mentioned, you can kind of hack around this. Do so at your own risk.

托管 C++、Delphi for .Net 和现在的 Delphi Prism 都使用非托管导出支持开箱即用。按照设计,C# 和 VB.net 不会。不知道为什么。但正如 Cobus 提到的,你可以解决这个问题。这样做自担风险。

In addition to Hydra from RemObjects, AToZed is introducing CrossTalk.

除了 RemObjects 的 Hydra 之外,AToZed 还引入了CrossTalk

回答by Rob Kennedy

I found a post from Robert Gieseckeon the Delphi Prism newsgroups. In it, he announces a project you can add to a solution that lets you export arbitrary functions from a .Net DLL simply by adding the DllExportattribute to them. It supports marshaling just like DllImport. He demonstrates it with a Prism project, but I imagine it would work on C# classes as well. The post was made in March, so I'm not sure whether the attachment will still be available. The May release of Prism obviates such a tool since it supports unmanaged exports by itself.

我在 Delphi Prism 新闻组上找到了Robert Giesecke帖子。在其中,他宣布了一个项目,您可以将其添加到解决方案中,该解决方案让您只需向 .Net DLL 中添加DllExport属性即可从它们导出任意函数。它支持编组,就像DllImport. 他用 Prism 项目演示了它,但我想它也适用于 C# 类。帖子是在三月份发布的,所以我不确定附件是否仍然可用。5 月发布的 Prism 消除了这种工具,因为它本身支持非托管导出。

回答by skamradt

I have been down this road before. The solution I picked was to create a NEWC# assembly (I later ported this to Prism) which exposed via com interop the functionality I needed to reach. I was finding by black boxing the API calls into something simpler, I was able to reduce the number of classes I had to deal with across the interop barrier.

我以前一直在这条路上。我选择的解决方案是创建一个新的C# 程序集(我后来将其移植到 Prism),它通过 com interop 公开了我需要达到的功能。我发现通过将 API 调用黑盒化为更简单的东西,我能够减少我必须跨越互操作障碍处理的类的数量。

I did look at Hydra, but it was overkill for what I was trying to do... which was access a 3rd party SDK which was presented in .net assemblies to process data. If you are looking at embedding the functionality (gui objects, ect) in your application then you should give Hydra some consideration.

我确实看过 Hydra,但它对我想要做的事情来说太过分了……这是访问在 .net 程序集中呈现的 3rd 方 SDK 来处理数据。如果您正在考虑在您的应用程序中嵌入功能(gui 对象等),那么您应该考虑 Hydra。

I did use Managed.VCL for a very early version of the system, but later abandoned it for the Prism/C# com interop approach which was simpler to deploy, and more stable.

我确实在系统的早期版本中使用了 Managed.VCL,但后来放弃了它,转而使用 Prism/C# com 互操作方法,这种方法更易于部署且更稳定。

回答by Cameron MacFarland

I'm assuming here that the Delphi app is not a .NET based app and therefore you need to host the .NET runtime in a Win32 process.

我在这里假设 Delphi 应用程序不是基于 .NET 的应用程序,因此您需要在 Win32 进程中托管 .NET 运行时。

CorBindToRuntimeEx is a function inside MSCorEE.dll, which holds the .NET runtime. With it you can host the runtime and then create objects inside it and interact with them.

CorBindToRuntimeEx 是 MSCorEE.dll 中的一个函数,它保存 .NET 运行时。有了它,您可以托管运行时,然后在其中创建对象并与之交互。