2

我有一个 Delphi DLL,其函数定义为:

函数 SubmitJobStringList(joblist: tStringList; var jobno: Integer): Integer;

我从 C# 调用它。如何将第一个参数声明为 C# 中不存在的 tStringList。我目前的声明为:

[DllImport("opt7bja.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
public static extern int SubmitJobStringList(string[] tStringList, ref int jobno);

但是当我调用它时,我得到一个内存访问冲突异常。

任何人都知道如何从 C# 正确传递给 tStringList 吗?

4

7 回答 7

13

你很可能不会有任何运气。TStringList 不仅仅是一个数组,它还是一个成熟的类,而且确切的实现细节可能与 .NET 可能的不同。查看 Delphi VCL 源代码(即,如果你有的话)并尝试找出是否可以在 C# 中重建类,并在你最好的朋友 Interop Marshaller 的帮助下传递它。请注意,即使 Delphi 字符串类型与 .NET 字符串类型不同,并且在不告诉编组器应该做什么的情况下传递它,他很可能会将其作为字符数组传递。

除此之外,我建议更改 Delphi DLL。在非 Delphi 客户端使用的 DLL 中公开任何特定于 Delphi 的东西从来都不是一件好事。将参数设为 PChar 数组,你应该没问题。

于 2008-09-30T09:07:14.110 回答
2

如果这是您的 DLL,我会重写该函数以接受字符串数组。避免将类作为 DLL 参数传递。

或者,如果您出于某种原因真的想使用 TStringList,则可以从任何 .Net 语言使用 Delphi 的 VCL.Net。

使用 TINiFile 的旧示例:http: //cc.codegear.com/Item/22691

该示例在 Delphi 2005 中使用 .Net 1.1。Delphi 2006 和 2007 支持 .Net 2.0。

于 2008-09-30T10:03:36.547 回答
1

如果您不控制 DLL 并且他们不能或不会更改它,您总是可以在单独的 DLL 中编写自己的 Delphi 包装器,并使用更跨语言友好的参数。

将类作为 DLL 函数的参数确实是一种不好的形式。

于 2008-09-30T10:12:40.100 回答
0

我不太清楚你使用 delphi 和 C# 的方式。看来您已经创建了一个要从 C# 调用的 Win32 DLL。当然,您必须为此使用 PInvoke。

我建议您使用您的源代码创建一个 .NET DLL,因为可以完全移植 VCL。如果您愿意,我可以进一步详细说明......

于 2008-09-30T09:12:25.780 回答
0

从理论上讲,您可以通过使用指针(将它们转换为 C# IntPtr 类型)而不是强类型对象引用(或者可能将它们包装成其他类型以避免必须声明不安全块)来执行此类操作,但基本的问题是this:Delphi 运行时必须是为对象分配和释放内存的机制。为此,您必须在 Delphi 编译的 DLL 中声明调用 TStringList 类的构造函数和析构函数的函数,您必须确保 Delphi DLL 使用 ShareMem 单元,并且您必须负责增加和减少引用计数为您的 Delphi AnsiStrings 在离开 DLL 之前和进入之后,最好也作为从您的 Delphi DLL 导出的函数。

简而言之,这是很多工作,因为您必须在同一个进程中处理两个内存管理器(.NET CLR 和 Delphi 的分配器),并且您必须手动管理内存“欺骗”Delphi 内存管理器和运行时。您是否有特殊原因必须使用此设置?你能描述一下你试图在更高层次上解决的问题吗?

于 2008-09-30T09:29:24.367 回答
0

正如 Hemant Jangid 所说,您应该可以通过将代码编译为 .NET dll 然后在您的 c# 项目中引用该程序集来轻松地做到这一点。

当然,只有当您拥有的 Delphi 版本具有 Delphi.NET 时,您才能执行此操作。

于 2008-09-30T09:48:34.493 回答
0

我对 c# 了解不多,但我用于跨上下文传输字符串列表的一种技术是使用 .text 属性来获取表示列表的字符串,然后在“另一端”分配该属性。

通常更容易将一根绳子穿过墙壁,因为它是一个完整的物体。

于 2008-10-01T03:45:25.637 回答