c++函数原型:
int __stdcall misposTrans(void* input, void* output)
c++结构原型:
typedef struct
{
char TransType[2]; //交易代码
char CardNo[19]; //卡号
char Amount[12]; //交易金额
char Tip[12]; //小费金额(暂时不用,空格补齐)
}} ST_ICBC_MIS;
c#调用原型:
//C++ 的char对应C#的Byte类型,不是char,在C#中char是16位的。
[DllImport("KeeperClient.dll", EntryPoint = "misposTrans", CallingConvention = CallingConvention.StdCall)]
public static extern int misposTrans(ref ST_ICBC_MIS input, out ST_ICBC_MIS output);
c#结构:
public struct ST_ICBC_MIS
{
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)] //这里的2就是数组长度
public Byte[] TransType; //交易代码
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 19)]
public Byte[] CardNo; //卡号
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 12)]
public Byte[] Amount; //交易金额
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 12)]
public Byte[] Tip; //小费金额(暂时不用,空格补齐)
}
C#调用过程:
ST_ICBC_MIS strInput = new ST_ICBC_MIS();//初始化结构
ST_ICBC_MIS strOutput= new ST_ICBC_MIS();//初始化结构
strInput.TransType = new Byte[2];
strInput.CardNo = new Byte[19] ;
strInput.Amount = new Byte[12] ;
strInput.Tip = new Byte[12] ;
Byte[] buf = new Byte[2]{0, 9};//赋值
strInput.TransType = buf;
int i = IcbcMis.misposTrans(ref strInput, out strOutput);
这里报错!
{"未能封送类型,因为嵌入数组实例的长度与布局中声明的长度不匹配。"}
请指正!!!万分感谢!
------解决思路----------------------
[DllImport("KeeperClient.dll", EntryPoint = "misposTrans", CallingConvention = CallingConvention.StdCall)]
public static extern int misposTrans(ref ST_ICBC_MIS input, out ST_ICBC_MIS output);
将out改为ref试一试,依稀记得out和C++里**对应
还不行的话,
传送非托管参数,并固定住别让GC回收了
ST_ICBC_MIS strInput = new ST_ICBC_MIS();
GCHandle un_strInput = GCHandle.Alloc(strInput, GCHandleType.Pinned);
ST_ICBC_MIS strOutput = new ST_ICBC_MIS();
GCHandle un_strOutput = GCHandle.Alloc(strOutput, GCHandleType.Pinned);
调用:
int i = IcbcMis.misposTrans(ref un_strInput.AddrOfPinnedObject(), ref un_strOutput.AddrOfPinnedObject());
输出参数out还是ref各试一次吧
……
un_strInput.Free();
un_strOutPut.Free();
------解决思路----------------------
更正下,调用时,实参前都不加ref
------解决思路----------------------
C++要4字节的指针,你传了整个的结构体,内存匹配不上吧(使用ref和out没尝试过,不知道会不会转成指针,如果转成了指针就忽略后面说的吧)。我有两个没试过的想法,LZ可以试试:
1. 在C#结构体上添加[MarshalAs(UnmanagedType.LPStruct)]
2. 函数声明为
[DllImport("KeeperClient.dll", EntryPoint = "misposTrans", CallingConvention = CallingConvention.StdCall)]
public static extern int misposTrans(IntPtr input, IntPtr output);
使用Marshal.StructureToPtr将结构体转换成IntPtr传入
------解决思路----------------------
你现在的问题是代码的逻辑太混乱了
你先alloc了一个ptr,然后把strInput转换给了ptr,最后释放的ptr是指向strInput的,最初分配的那块内存已经泄露了
------解决思路----------------------
结构的定义使用 structLayout 属性。
不要再为结构里面的数组字段赋值了。
这也字段直接包含在 结构里面。