c#调用Delphi DLL参数为结构体数组

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了c#调用Delphi DLL参数为结构体数组相关的知识,希望对你有一定的参考价值。

Delphi结构体如下
PICRecord=^TICRecord;
TICRecord=packed record
Card: array[0..19] of char;
timeString: array[0..19] of char;
EmpId: array[0..9] of char;
mark: Integer;
flag: Integer;
cardTimes: Integer;
end;
Delphi相关DLL函数
function AddData(var A:integer;var Records:array of TICRecord):integer; stdcall;
var
i ,Count :integer;
begin
Count:=16;

for i:=0 to Count do
begin
Records[i].Card:='1789456456';
end;
result:=A;
end;
exports AddData;
C#结构体如下
public struct TICRecord

[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 21)]
public string Card; // 卡号字符串
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 21)]
public string TimeString; // 14位刷卡时间字符串, 格式为yyyymmddhhnnss
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 11)]
public string EmpID;
public Int32 Mark; // 读卡机标识字符
public Int32 Flag; // 存储卡的结果
public Int32 CardTimes; // 发卡次数, 0-15


C#调用方法
[DllImport("Test.dll", EntryPoint = "AddData", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
public static extern Int32 AddData(ref Int32 A,[In,Out] TICRecord[] B, Int32 Records_Size);

TICRecord[] TICRecordList = new TICRecord[Records_Size];
int Result = DongBao.AddData(ref a, TICRecordList, Records_Size);

MessageBox.Show( "返回值:"+Result+ "");

string Str = "";
for (int i = 0; i < Records_Size; i++)

Str += i + " ";
Str += Encoding.UTF8.GetString(Encoding.UTF8.GetBytes(TICRecordList[i].Card)) + "\r\n";



MessageBox.Show("如果成功则返回100:现在返回的是" + Str + "");

返回结果,只有第一条有记录,其他的都为空,求处理过相关问题的老师指导一下

function AddData(var A:integer;var Records:array of TICRecord):integer; stdcall;
2个参数

public static extern Int32 AddData(ref Int32 A,[In,Out] TICRecord[] B, Int32 Records_Size);

3个参数
??????????????
参考技术A 没有看明白

关于JAVA调用C的DLL库中的函数问题,传入一个含有指针的结构体指针

比如有个结构体:

typedef struct _SSM_EVENT



WORD wEventCode; //事件编码

int nReference; //参考值

PVOID pvBuffer; //事件信息缓冲指针

 DWORD dwParam; //输出参数

SSM_EVENT, *PSSM_EVENT;

PVOID是一个指向300空间的一个指针,可以理解为一个char[]数组,现在java需要调用c里dll库的一个函数,其中一个参数为该结构体指针*PSSM_EVENT,传入时有的参数含有值。1.那么我该如何传入这个带有值的参数。2.我该怎么获取这个结构体的值,尤其是指针的值。无论是使用jnative,jna,jin什么样的第三方jar包都可以。
结构体里面含有一个指针的属性,在JAVA分配创建一段内存,我通过第三方JAR包传递并返回这段内存,该JAR包提供的函数可以读取这段内存里面的值,但现在由于上述的结构,这段内存里面含有一个指针值,也就是说在返回的这段内存里面的值里,由一个指针地址值,但我需要的是这个指针指向的地址里面的数据,而不是这个指针地址值,我该怎么取呢?现在这个是最主要的问题了

参考技术A 在java里定义对应的,分配地址空间大小相同的结构体。
java应该也可以定义struct.
比如dword可以定义为long.
把c中的pvoid定义找出来,也定义一个struct.追问

定义结构体没有问题,现在关键是JAVA没有指针的概念,而dll库需要传递的是一个结构体指针,关键是指针,怎么传。现在这个问题已经解决了,还有另外一个问题,请看我的追加提问

追答

c还是可以重调java的,可以参考网上资料,指针地址什么的,可以传递。这个你自己考虑一下。

追问

那这样就更麻烦了,我可以在c++重新写个函数,调用DLL,返回需要的值。但是因为现在比较急,我没有时间研究那么多的,所以我想尽量只在JAVA做,现在就差这一步了。

追答

java的变量就是指针,定义java结构体后,一样可以取到相同的值。c是什么值,java就是什么值。

追问

c传回来是指针,是个地址值,java现在能获取到的是这个地址值,怎么通过这个地址值去获取内存的数据?

参考技术B 没做过这么复杂的。
但你想调用DLL,
应该是通过native生成的方法。你通过这个方法中的参数进行交互。
参考技术C 我觉得用java调用这个肯定是使用jni了。这个是无疑了,网上jni的api和教程挺多的。查查就知道了。然后说得到指针指向的值而不是地址,这步操作是c语言的语法问题,也就是说c的源码取值和取地址那里写对了就可以了。jni只是用来调用的。

以上是关于c#调用Delphi DLL参数为结构体数组的主要内容,如果未能解决你的问题,请参考以下文章

C#如何调用C++的DLL的结构体数组指针

C#引用c++DLL结构体数组注意事项(数据发送与接收时)

Delphi调用Dll返回结构体的问题?

C#和C++传递结构体

关于JAVA调用C的DLL库中的函数问题,传入一个含有指针的结构体指针

C#调用delphi记录结构体问题