Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/backbone.js/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
tStringList将C#传递到Delphi DLL_C#_Delphi_Dll_Tstringlist - Fatal编程技术网

tStringList将C#传递到Delphi DLL

tStringList将C#传递到Delphi DLL,c#,delphi,dll,tstringlist,C#,Delphi,Dll,Tstringlist,我有一个Delphi DLL,其函数定义为: 函数SubmitJobStringList(作业列表:tStringList;变量作业号:Integer):整数 我是从C#打来的。如何将第一个参数声明为C#中不存在的tStringList。我目前的声明如下: [DllImport("opt7bja.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)] public static extern in

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

函数SubmitJobStringList(作业列表:tStringList;变量作业号: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,你很可能不会有任何运气。TStringList不仅仅是一个数组,它是一个成熟的类,确切的实现细节可能与.NET不同。查看Delphi VCL源代码(即,如果您有),并尝试找出是否可以在C#中重建类,并在您最好的朋友Interop Marshaller的帮助下传递它。请注意,即使Delphi字符串类型也不同于.NET字符串类型,并且在不告诉封送员应该做什么的情况下传递它,他很可能会将其作为字符数组传递


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

我不太清楚您使用delphi和C#的方式。似乎您已经创建了一个Win32 DLL,希望从C#调用它。当然,你一定是在用PInvoke

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

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


简而言之,这是大量的工作,因为您必须在同一个进程中处理两个内存管理器(.NET CLR和Delphi的分配器),并且必须手动管理内存并“愚弄”Delphi内存管理器和运行时。您绑定到此设置有特殊原因吗?您能描述一下您试图在更高级别上解决的问题吗?

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


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

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

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

使用TIniFile的旧示例:


该示例使用Delphi2005中的.NET1.1。Delphi 2006和2007支持.Net 2.0。

如果您不控制DLL,并且他们不能或不会更改它,则您可以始终在单独的DLL中编写自己的Delphi包装,其中包含更为跨语言友好的参数

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

我对c#知之甚少,但我用于跨上下文传输StringList的一种技术是使用.text属性获取表示该列表的字符串,然后在“另一端”分配该属性

在墙上挂一根绳子通常比较容易,因为它是一个完整的物体