如何使用C#创建DLL并在Delphi XE6中调用

6

我使用VS2013创建了一个DLL文件,方法是File/New Project/Class Library。然后我试图在Delphi中动态加载它。但是Delphi为过程GetProcAddress返回了NIL

我的C#和Delphi代码看起来像我下面发布的。在代码中,GetProcAddress返回NIL。请告诉我是否漏掉了什么。

C#代码

using System;
namespace TestDLL
{
    public class Class1
    {
        public static string EchoString(string eString)
        {
            return eString;
        }
    }
}

Delphi 代码

 Type
    TEchoString = function (eString:string) : integer;stdcall;

  function TForm1.EchoString(eString:string):integer;
  begin
    dllHandle := LoadLibrary('TestDLL.dll') ;
    if dllHandle <> 0 then
    begin
      @EchoString := GetProcAddress(dllHandle, 'EchoString') ;
      if Assigned (EchoString) then
            EchoString(eString)  //call the function
      else
        result := 0;
      FreeLibrary(dllHandle) ;
    end
    else
    begin
      ShowMessage('dll not found ') ;
   end;
end;

我按照“非托管程序”的建议更改了代码,但仍然没有运气。 - ary
我不理解那个评论。我撤销了你的编辑。请不要改变问题。可以添加更多内容以请求澄清,但不要进行完全使历史记录无效的更改。 - David Heffernan
此外,如果您不发布虚假代码,那将会更好。这段C#代码是虚假的。 - David Heffernan
谢谢David。我会记住的。 - ary
“public static string EchoString(string eString:string)” 不是有效的 C# 代码,也与 Delphi 代码完全不匹配。 - David Heffernan
1个回答

4
一个C# DLL是一个托管程序集,而不是通过经典的PE导出其功能。你有以下选择:
  1. 使用C++/CLI混合模式来包装C#。然后可以以通常的非托管模式导出函数。
  2. 使用Robert Giesecke的 UnmanagedExports。这可能比C++/CLI包装器更方便。
  3. 将托管功能作为COM对象公开。
一旦你选择其中之一,就必须处理对string数据类型的误用。那是一种私有的Delphi数据类型,不适用于交互操作。对于问题中的简单示例,PWideChar就足够了。

我刚刚标记为重复并链接到您之前的答案!在您的答案评论中,甚至提到了这个问题被问得有多频繁 :-) 尽管如此,我仍然给您的答案点了赞! - Belogix
嗯,并非全部都这样。以下是您的选择。UnmanagedExports 是最简单的选项。 - David Heffernan
安装Nuget包后,我在echostring函数上方添加了这段代码[DllExport("echostring", CallingConvention = CallingConvention.StdCall)]。但是Delphi仍然找不到该过程。我还缺少什么?谢谢。 - ary
函数名称不匹配。你必须正确区分大小写。另外,停止使用字符串至少一会儿。看看是否可以使用简单的整数获得成功。然后转移到更复杂的数据。请查看我的更新。最后,使用“external”而不是运行时链接。它使代码变得简单得多。 - David Heffernan
有人尝试过这个吗:http://www.managed-vcl.com/downloads/full/? - MBWise
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接