C#调用Delphi dll

wt57191187 2011-03-18 02:00:42

函数原型:
语法:
function BatchReadRecord(hPort: THandle; var Records: array of TICRecord{; ArraySize: Integer}): Integer;

参数说明:
hPort: 端口句柄, 调用OpenCommPort函数得到,需要联机
Records: 返回记录数组, 最少需要16个单元
ArraySize: Delphi不需要,如果是VB或是C++需要传数组大小参数
TICRecord :结构中包含一条记录

//TICRecord结构体:
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;
consume : WORD;
balance : WORD;
end;




//我在C#中的调用:
[DllImport("EastRiver.dll", EntryPoint = "BatchReadRecord", SetLastError = true, CharSet = CharSet.Auto, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
public static extern IntPtr BatchReadRecord(IntPtr hPort, ref TICRecord[] array);

//定义结构体
[StructLayout(LayoutKind.Sequential)]
public struct TICRecord
{
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 20)]
public char[] Card;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 20)]
public char[] TimeString;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 10)]
public char[] EmpId;
public int Mark;
public int Flag;
public int CardTimes;
public int Consume;
public int Balance;
}

private void btn_BatchReadRecord_Click(object sender, EventArgs e)
{
EastRiver.TICRecord[] array = new EastRiver.TICRecord[16];
for (int i = 0; i < array.Length; i++)
{
EastRiver.TICRecord tr = array[i];
tr.Card = new char[20];
tr.TimeString = new char[20];
tr.EmpId = new char[10];
tr.Mark = 0;
tr.Flag = 0;
tr.CardTimes = 0;
tr.Consume = 0;
tr.Balance = 0;
}
IntPtr ret = EastRiver.BatchReadRecord(hPort,ref array);
//这里报错:无法封送处理类型为“TICRecord”的字段“Card”: 无效的托管/非托管类型组合(数组字段必须与 ByValArray 或 SafeArray 成对出现)。
}


请问大家这个问题如何解决?谢谢!
...全文
254 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
lixigao 2012-08-27
  • 打赏
  • 举报
回复
你的问题是 [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 20)]
public char[] TimeString;

[MarshalAs(UnmanagedType.ByValArray, SizeConst = 21)]
public char[] Card;
要为这样,就不会报错,如果的处理好,就麻烦楼主传一下经验,发到我邮箱一下lixigao2012@126.com
lixigao 2012-08-27
  • 打赏
  • 举报
回复
楼主,你的C#传结构体数组的问题,处理好了吗,我现在也在处理想同的问题,但是只能取得第一条结构体数据,其他的都取不到,
qldsrx 2011-03-18
  • 打赏
  • 举报
回复

//定义结构体
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct TICRecord
{
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 20)]
public string Card;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 20)]
public string TimeString;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 10)]
public string EmpId;
public int Mark;
public int Flag;
public int CardTimes;
public short Consume;
public short Balance;
}

如果是Delphi7以前的版本,肯定是用Ansii字符,以后的版本就是Uncode字符了,居然不统一,郁闷。
bdmh 2011-03-18
  • 打赏
  • 举报
回复
去掉诸如new char[20];的初始化试试
EastonSoft 2011-03-18
  • 打赏
  • 举报
回复
可以调用的,我以前写过。现在忘了,要翻看以前的代码。
threenewbee 2011-03-18
  • 打赏
  • 举报
回复
调用不起来。除非 Delphi 将函数声明为 stdcall 方式。
636f6c696e 2011-03-18
  • 打赏
  • 举报
回复
C#哪里来char[]....
C#的struct不能像C++那样写
举个例子你好好看看
using   System.Runtime.InteropServices; 

[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Ansi, Pack=1)]
public struct TDataBrokerInputOptions
{
[MarshalAs(UnmanagedType.ByValArray, SizeConst=128)]
public byte[] szProxyName ;

[MarshalAs(UnmanagedType.LPStr)]
public string pszIPRestrictList;
}

[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Ansi, Pack=1)]
public struct TDataBrokerOptions
{
[MarshalAs(UnmanagedType.LPStr)]
public string pzServerType;

public IntPtr zVSize;
}

111,119

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • AIGC Browser
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧