创建一个可以使用 stdcall 在 Delphi 应用程序中导入的 C# DLL - 可能吗?
我有一个程序需要为其创建 DLL,希望是用 C# 编写的。 该程序是用 Delphi 编写的,我有一个可编码的接口文件。 该接口使用 stdcall 调用约定。
是否可以创建一个符合接口并且可以在Delphi应用程序中使用的C# DLL?
是否有一些示例代码演示如何将 C# DLL 编码为 stdcall 接口方法?
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.
Is it possible to create a C# DLL that conforms to the interface and can be used in the Delphi application?
Is there some sample code that demonstrates how to code the C# DLL to a stdcall interface method?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(9)
这在纯 C# 中是不可能的,但是 这篇文章展示了如何将非托管导出表添加到您的 C# 库,然后可以在任何其他语言中使用该表。 请注意,大量对 Blitz 的引用不应让您望而却步 - 它们与作者自己的上下文有关,与基本概念及其工作原理无关。
Brian Long 的一次会议中还有一节纸。 有点讽刺的是,Delphi.Net 实际上直接支持非托管导出,尽管 C# 不这样做。 我不知道 Delphi Prism 是否也是如此。
This is not possible in pure C#, but this is an article that 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.
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.
我以前也走过这条路。 我选择的解决方案是创建一个新 C# 程序集(后来我将其移植到 Prism),它通过 com 互操作公开了我需要实现的功能。 我发现通过将 API 调用黑盒化为更简单的东西,我能够减少必须跨互操作障碍处理的类的数量。
我确实看过 Hydra,但它对于我想要做的事情来说有点过分了……访问 .net 程序集中提供的第 3 方 SDK 来处理数据。 如果您正在考虑在应用程序中嵌入功能(gui 对象等),那么您应该考虑 Hydra。
我确实在系统的早期版本中使用了 Managed.VCL,但后来放弃了它,转而使用 Prism/C# com 互操作方法,该方法部署更简单,也更稳定。
I have been down this road before. The solution I picked was to create a NEW C# 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.
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.
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.
看看 Hydra
Have a look at Hydra
出于好奇,您为什么希望编写一个旨在从 C# 本机应用程序中使用的 .dll?
托管 C++、Delphi for .Net 以及现在的 Delphi Prism 都使用非托管导出支持开箱即用。 按照设计,C# 和 VB.net 不这样做。 不知道为什么。 但正如科布斯提到的,你可以解决这个问题。 这样做自担风险。
除了 RemObjects 的 Hydra 之外,AToZed 还推出了 CrossTalk。
Out of curiosity, why are you hoping to write a .dll that's intended to be used from a native application in C#?
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.
In addition to Hydra from RemObjects, AToZed is introducing CrossTalk.
我在 Delphi Prism 新闻组上找到了 Robert Giesecke 的帖子。 在其中,他宣布了一个项目,您可以将其添加到解决方案中,只需向 .Net DLL 添加
DllExport
属性即可从 .Net DLL 导出任意函数。 它支持像DllImport
一样的封送处理。 他通过 Prism 项目演示了它,但我想它也适用于 C# 类。 该帖子是三月份发布的,所以我不确定附件是否仍然可用。 五月份发布的 Prism 消除了这种工具,因为它本身支持非托管导出。I found a post from Robert Giesecke on 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
DllExport
attribute to them. It supports marshaling just likeDllImport
. 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.您需要使程序集 (=C# DLL) 可供 COM 访问,这称为 Interop。
请参阅 MSDN 文章汇编到类型库转换和打包 COM 程序集,其中描述了技术背景和执行所需操作的实用程序。
You need to make the assembly (=C# DLL) accessible to COM, which is called Interop.
See MSDN articles Assembly to Type Library Conversion and Packaging an Assembly for COM which describe the technical background and the utilities to perform the required operations.
我在这里假设 Delphi 应用程序不是基于 .NET 的应用程序,因此您需要在 Win32 进程中托管 .NET 运行时。
CorBindToRuntimeEx 是 MSCorEE.dll 中的一个函数,它保存 .NET 运行时。 使用它,您可以托管运行时,然后在其中创建对象并与它们交互。
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.
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.
我很确定这不能直接完成。 您必须使用 C++/CLI 编写一个层,或者将 C# 代码公开为 ActiveX 接口。 但第二个选项可能不符合您的界面。
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# 是托管代码。 这意味着它需要一个非常特定的运行时环境才能运行,而 Delphi 无法直接提供该环境。 它不像C那样简单地找到函数的地址和调用约定并调用它。
但是,可以在 Delphi 应用程序(或任何其他 Windows 应用程序)内托管公共语言运行时。 我不知道该怎么做。 我只知道这是可能的。 (史蒂夫提到的“九头蛇”很可能就是这么做的。)
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.
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.)