tStringList将C#传递给Delphi DLL

时间:2008-09-30 08:42:37

标签: c# delphi dll tstringlist

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

function 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?

7 个答案:

答案 0 :(得分:13)

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

除此之外,我建议更改Delphi DLL。在非Delphi客户端使用的DLL中暴露特定于Delphi的东西永远不是一件好事。使参数成为PChar的数组,你应该没问题。

答案 1 :(得分: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。

答案 2 :(得分:1)

如果你不控制DLL并且它们不能或不会改变它,你总是可以在一个单独的DLL中编写自己的Delphi包装器,其中的参数更具有跨语言友好性。

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

答案 3 :(得分:0)

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

我建议您使用源代码创建.NET DLL,因为可以完全移植VCL。如果你愿意,我可以进一步阐述......

答案 4 :(得分:0)

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

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

答案 5 :(得分:0)

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

当然,如果您拥有的Delphi版本具有Delphi.NET,您将只能这样做。

答案 6 :(得分:0)

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

通常更容易在墙上划一条绳子,它是一个完整的物体。