编辑:我已经发布了更好的实现方法,请往下看。我在这里留下这个,以便回复是有意义的。
我已经做过许多搜索,寻找在Delphi中编写DLL并能够从C#中调用它、传递和返回字符串的正确方法。很多信息都是不完整或不正确的。经过多次尝试,我找到了解决方案。
这是使用Delphi 2007和VS 2010编译的。我认为它在其他版本中也可以正常工作。
以下是Delphi代码。记得在项目中包含版本信息。
library DelphiLibrary;
uses SysUtils;
// Compiled using Delphi 2007.
// NOTE: If your project doesn't have version information included, you may
// receive the error "The "ResolveManifestFiles" task failed unexpectedly"
// when compiling the C# application.
{$R *.res}
// Example function takes an input integer and input string, and returns
// inputInt + 1, and inputString + ' ' + IntToStr(outputInt) as output
// parameters. If successful, the return result is nil (null), otherwise it is
// the exception message string.
// NOTE: I've posted a better version of this below. You should use that instead.
function DelphiFunction(inputInt : integer; inputString : PAnsiChar;
out outputInt : integer; out outputString : PAnsiChar)
: PAnsiChar; stdcall; export;
var s : string;
begin
outputInt := 0;
outputString := nil;
try
outputInt := inputInt + 1;
s := inputString + ' ' + IntToStr(outputInt);
outputString := PAnsiChar(s);
Result := nil;
except
on e : exception do Result := PAnsiChar(e.Message);
end;
end;
// I would have thought having "export" at the end of the function declartion
// (above) would have been enough to export the function, but I couldn't get it
// to work without this line also.
exports DelphiFunction;
begin
end.
以下是C#代码:
using System;
using System.Runtime.InteropServices;
namespace CsharpApp
{
class Program
{
// I added DelphiLibrary.dll to my project (NOT in References, but
// "Add existing file"). In Properties for the dll, I set "BuildAction"
// to None, and "Copy to Output Directory" to "Copy always".
// Make sure your Delphi dll has version information included.
[DllImport("DelphiLibrary.dll",
CallingConvention = CallingConvention.StdCall,
CharSet = CharSet.Ansi)]
public static extern
string DelphiFunction(int inputInt, string inputString,
out int outputInt, out string outputString);
static void Main(string[] args)
{
int inputInt = 1;
string inputString = "This is a test";
int outputInt;
string outputString;
// NOTE: I've posted a better version of this below. You should use that instead.
Console.WriteLine("inputInt = {0}, intputString = \"{1}\"",
inputInt, inputString);
var errorString = DelphiFunction(inputInt, inputString,
out outputInt, out outputString);
if (errorString != null)
Console.WriteLine("Error = \"{0}\"", errorString);
else
Console.WriteLine("outputInt = {0}, outputString = \"{1}\"",
outputInt, outputString);
Console.Write("Press Enter:");
Console.ReadLine();
}
}
}
我希望这些信息能够帮助其他人,让他们不必像我一样抓狂。
COM
,那么在C#中使用它就很容易了。我进行了一些搜索,并找到了一些关于Delphi和COM关系的资源,网址在这里:http://delphi.about.com/library/weekly/aa122804a.htm - Saeed AmiriDelphiFunction
函数结束时,s
的引用计数将为零,因此s
所使用的内存将返回给内存分配器,并且在C#调用程序可以获取内容之前可能会被其他内容使用(和覆盖)。当发生这种情况时,各种破坏将会发生。在多线程情况下(特别是在多核系统上),这可能会很快发生。 - Jeroen Wiert Pluimers