求助:在C#中如何调用Dephi写的接口函数(内含结构体及结构体指针)
==================================================================================
接口中的数据结构定义
//查询卡返写区结构
Type
TCheckReturn = Record
str_Mark: String[2]; //返写标志
e_Left: Double; //剩余电量
e_SumBuy: Double; //累计购电量
e_Overall: Double; //当前总累计用电量
e_Tine: Double; //当前尖累计用电量
e_Apex: Double; //当前峰累计用电量
e_Calm: Double; //当前平累计用电量
e_Vale: Double; //当前谷累计用电量
e_reverse: Double; //反向电量
str_State: String[2]; //水表工作状态字
str_MeterNo: String[12]; //电表表号
str_Date: String[6]; //当前日期
e_Freeze3: Double; //冻结电量3
e_Freeze2: Double; //冻结电量2
e_Freeze1: Double; //冻结电量1
str_FreezeTime: String[2]; //电量冻结日
str_UserNo: String[12]; //用户号
i_Times: Integer; //购电次数
e_Alarm1: Double; //报警电量1
e_Alarm2: Double; //报警电量2
e_OverValue: Double; //透支电量限额
e_InputValue: Double; //囤积电量限额
End;
PCheckReturn = ^TCheckReturn;
//根密钥
Type
TRootKey = Record
str_MainKey: String[32]; //电表主控密钥
str_InsideKey: String[32]; //系统内部认证密钥
str_MeterReturnKey: String[32]; //电表反馈外部认证主密钥
str_EleInfoKey: String[32]; //电量外部认证密钥
str_EleReturnKey: String[32]; //电表返写数据加密密钥
str_DecryptKey: String[32]; //电表购电数据解密密钥
str_BuyEleKey: String[32]; //电表购电外部认证密钥
End;
以下是接口中的函数原型:
//发检查卡
Function MadeCheck(CommHandle: THandle; TRK: TRootKey; Var i_Error: Integer):
Boolean; StdCall; External 'EleMeter.DLL';
//读检查卡
Function ReadCheck(CommHandle: THandle; CheckReturn: PCheckReturn; Var i_Error:
Integer): Boolean; StdCall; External 'EleMeter.DLL';
==========================================================================
在C#中的代码:
结构定义:
//查询卡返写区结构
[StructLayout(LayoutKind.Sequential)]
public struct CheckReturn
{
//Type
// TCheckReturn = Record
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
public char[] strMark;// str_Mark: String[2]; //返写标志
public double dLeft; // e_Left: Double; //剩余电量
public double dSumBuy; // e_SumBuy: Double; //累计购电量
public double dOverall; // e_Overall: Double; //当前总累计用电量
public double dTine; // e_Tine: Double; //当前尖累计用电量
public double dApex; // e_Apex: Double; //当前峰累计用电量
public double dCalm; // e_Calm: Double; //当前平累计用电量
public double dVale; // e_Vale: Double; //当前谷累计用电量
public double dReverse; // e_reverse: Double; //反向电量
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
public char[] strState; // str_State: String[2]; //水表工作状态字
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 12)]
public char[] strMeterNo; // str_MeterNo: String[12]; //电表表号
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)]
public char[] strDate; // str_Date: String[6]; //当前日期
public double dFreeze3; // e_Freeze3: Double; //冻结电量3
public double dFreeze2; // e_Freeze2: Double; //冻结电量2
public double dFreeze1; // e_Freeze1: Double; //冻结电量1
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
public char[] strFreezeTime; // str_FreezeTime: String[2]; //电量冻结日
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 12)]
public char[] strUserNo; // str_UserNo: String[12]; //用户号
public int iTimes; // i_Times: Integer; //购电次数
public double dAlarm1; // e_Alarm1: Double; //报警电量1
public double dAlarm2; // e_Alarm2: Double; //报警电量2
public double dOverValue; // e_OverValue: Double; //透支电量限额
public double dInputValue; // e_InputValue: Double; //囤积电量限额
// End;
// PCheckReturn = ^TCheckReturn;
public void init()
{
strMark = "99".ToCharArray();
dLeft = 9.9;
dSumBuy = 9.9;
dOverall = 9.9;
dTine = 9.9;
dApex = 9.9;
dCalm = 9.9;
dVale = 9.9;
dReverse = 9.9;
strState = "99".ToCharArray();
strMeterNo = "999999999999".ToCharArray();
strDate = "999999".ToCharArray();
dFreeze3 = 9.9;
dFreeze2 = 9.9;
dFreeze1 = 9.9;
strFreezeTime = "99".ToCharArray();
strUserNo = "999999999999".ToCharArray();
iTimes = 9;
dAlarm1 = 9.9;
dAlarm2 = 9.9;
dOverValue = 9.9;
dInputValue = 9.9;
}
}
//根密钥文件结构
[StructLayout(LayoutKind.Sequential)]
public unsafe struct RootKey
{
//Type
// TRootKey = Record
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)]
public char[] strMainKey; // str_MainKey: String[32]; //电表主控密钥
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)]
public char[] strInsideKey; // str_InsideKey: String[32]; //系统内部认证密钥
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)]
public char[] strMeterReturnKey; // str_MeterReturnKey: String[32]; //电表反馈外部认证主密钥
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)]
public char[] strEleInfoKey; // str_EleInfoKey: String[32]; //电量外部认证密钥
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)]
public char[] strEleReturnKey; // str_EleReturnKey: String[32]; //电表返写数据加密密钥
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)]
public char[] strDecryptKey; // str_DecryptKey: String[32]; //电表购电数据解密密钥
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)]
public char[] strBuyEleKey; // str_BuyEleKey: String[32]; //电表购电外部认证密钥
// End;
}
函数调用:
//发检查卡
//Function MadeCheck(CommHandle: THandle; TRK: TRootKey; Var i_Error: Integer):
// Boolean; StdCall; External 'EleMeter.DLL';
[DllImport("EleMeter.dll")]
private static extern bool MadeCheck(int THalde, RootKey rootKey, ref int iError);
public string fnMakeCheck(RootKey rootKey)
{
string strErrorInfo = "";
try
{
fnOpenCom();
bool isOK;
int iError = 0;
isOK = MadeCheck(m_hCardHandle, rootKey, ref iError);
if (!isOK)
{
strErrorInfo = fnGetError(iError);
}
}
catch (Exception exc)
{
strErrorInfo = exc.Message;
}
finally
{
fnCloseCom();
}
return strErrorInfo;
}
//读检查卡
//Function ReadCheck(CommHandle: THandle; CheckReturn: PCheckReturn; Var i_Error:
// Integer): Boolean; StdCall; External 'EleMeter.DLL';
[DllImport("EleMeter.dll")]
private static extern bool ReadCheck(int THandle, IntPtr checkReturnPtr, ref int iError);
public string fnReadCheck(IntPtr checkReturnPtr)
{
string strErrorInfo = "";
try
{
fnOpenCom();
bool isOK;
int iError = 0;
isOK = ReadCheck(m_hCardHandle, checkReturnPtr, ref iError);
if (!isOK)
strErrorInfo = fnGetError(iError);
}
catch(Exception exc)
{
strErrorInfo = exc.Message;
}
finally
{
fnCloseCom();
}
return strErrorInfo;
}
现在我在C#中调用上面的函数
public void fnCheckCardRead()
{
CheckReturn tcr = new CheckReturn();
tcr.init();//初始化结构体数据
string strRet = "";
IntPtr checkReturnPtr = Marshal.AllocHGlobal(Marshal.SizeOf(tcr));
Marshal.StructureToPtr(tcr, checkReturnPtr, true);
strRet = m_ICCard.fnReadCheck(checkReturnPtr);
if (strRet == "")
{
MessageBox.Show("读检查卡成功!");
}
else
{
MessageBox.Show(strRet);
}
}
public void fnCheckCardMake()
{
RootKey rootKey = new RootKey();
ICCardHelper.init(ref rootKey);//初始化结构体数据
string strRet;
strRet = m_ICCard.fnMakeCheck(rootKey);
if (strRet.Length == 0)
{
MessageBox.Show("发检查卡成功!");
}
else
{
MessageBox.Show(strRet);
}
}
结果读卡的函数成功了,但是checkReturn结构体中的数据没有任何变化,
而发卡程序也错了。
这个好像是因为C#中的结构体跟Dephi中的Record有区别才造成的吧?还是我调用的时候出错了?