某联接口由控件对象模式转为结构过程模式的操作
2016-09-23 14:49
666 查看
//输入输出的结构体变量 struct REQUEST { [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)] public char[] posid;//POS机号 [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)] public char[] operid; [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)] public char[] trans;//交易类型 [MarshalAs(UnmanagedType.ByValArray, SizeConst = 12)] public char[] amount;//金额 [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)] public char[] old_date;//原交易日期 [MarshalAs(UnmanagedType.ByValArray, SizeConst = 12)] public char[] old_reference;//原交易参/考号 [MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)] public char[] old_trace;//原凭证号 [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)] public char[] lrc;//LRC校验 }; struct RESPONSE { [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)] public char[] resp_code;//返回码 [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)] public char[] bank_code; //银行行号 [MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)] public char[] card_no; //卡号 [MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)] public char[] trace; //凭证号 [MarshalAs(UnmanagedType.ByValArray, SizeConst = 12)] public char[] amount; //金额 [MarshalAs(UnmanagedType.ByValArray, SizeConst = 40)] public char[] resp_chin;//错误说明 [MarshalAs(UnmanagedType.ByValArray, SizeConst = 15)] public char[] mei_id; //商户号 [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)] public char[] ter_id; //终端号 [MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)] public char[] batch_no; //批次号 [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)] public char[] txndate; //交易日期 [MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)] public char[] txntime; //交易时间 [MarshalAs(UnmanagedType.ByValArray, SizeConst = 12)] public char[] refdata; //系统参考号 [MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)] public char[] authcode; //授权号 [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)] public char[] stdate; //清算日期 [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)] public char[] lrc; //LRC校验 } [DllImport("posinf.dll", CharSet = CharSet.Ansi, SetLastError = true)] public static extern int bankall(char[] str1, byte[] str2);
最终调用:
StringBuilder str1; REQUEST strin; string str; str1 = new StringBuilder(); byte[] str2 = new byte[1024]; strin.posid = new char[8]; strin.posid = textBox1.Text.ToCharArray(); strin.operid = new char[8]; strin.operid = textBox2.Text.ToCharArray(); strin.trans = new char[2]; strin.trans = comboBox1.Text.Substring(0, 2).ToCharArray(); strin.amount = new char[12]; strin.amount = textBox4.Text.ToCharArray(); strin.old_date = new char[8]; strin.old_date = textBox5.Text.ToCharArray(); strin.old_reference = new char[12]; strin.old_reference = textBox6.Text.ToCharArray(); strin.old_trace = new char[6]; strin.old_trace = textBox7.Text.ToCharArray(); strin.lrc = new char[3]; strin.lrc = textBox8.Text.ToCharArray(); str1.Append(strin.posid); str1.Append(strin.operid); str1.Append(strin.trans); str1.Append(strin.amount); str1.Append(strin.old_date); str1.Append(strin.old_reference); str1.Append(strin.old_trace); str1.Append(strin.lrc); bankall(str1.ToString().ToCharArray(), str2); string tranresult; tranresult = System.Text.Encoding.GetEncoding("gb2312").GetString(str2); textBox9.Text = tranresult.Substring(0, 144); str = textBox9.Text.Substring(0, 2); if (str == "00") { textBox10.Text = textBox9.Text.Substring(0, 2); textBox11.Text = textBox9.Text.Substring(2, 4); textBox12.Text = textBox9.Text.Substring(6, 20); textBox13.Text = textBox9.Text.Substring(26, 6); textBox14.Text = textBox9.Text.Substring(32, 12); textBox24.Text = textBox9.Text.Substring(44, 36); textBox15.Text = textBox9.Text.Substring(80, 15); textBox16.Text = textBox9.Text.Substring(95, 8); textBox17.Text = textBox9.Text.Substring(103, 6); textBox18.Text = textBox9.Text.Substring(109, 4); textBox19.Text = textBox9.Text.Substring(113, 6); textBox20.Text = textBox9.Text.Substring(119, 12); textBox21.Text = textBox9.Text.Substring(131, 6); textBox22.Text = textBox9.Text.Substring(137, 4); textBox23.Text = textBox9.Text.Substring(141, 3); } else { textBox10.Text = textBox9.Text.Substring(0, 2); textBox24.Text = textBox9.Text.Substring(44, 36); }
相关知识:
作用:
MarshalAs属性指示如何在托管代码和非托管代码之间封送数据。
使用方法:
[MarshalAs(UnmanagedType unmanagedType, 命名参数)]
实际上相当于构造一个MarshalAsAttribute类的对象
常用的UnmanagedType枚举值:(详细内容查MSDN)
BStr 长度前缀为双字节的 Unicode 字符串;
LPStr 单字节、空终止的 ANSI 字符串。;
LPWStr 一个 2 字节、空终止的 Unicode 字符串;
ByValArray 用于在结构中出现的内联定长字符数组,应始终使用MarshalAsAttribute的SizeConst字段来指示数组的大小。
注意:
在用Marshal.SizeOf(),即获取对象的非托管大小时,获得的是自己定义的大小;
但在实际处理的时候,是按照实际的大小来获取的
示例:
定义一个固定大小的结构体,代码如下:
结构的声明:
[csharp] view
plain copy
struct Info
{
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
public char[] name;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
public char[] cipher;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 256)]
public char[] signature;
}
结构的使用:
[csharp] view
plain copy
Info myInfo;
myInfo.name = name.ToCharArray();
myInfo.cipher = cipher.ToCharArray();
myInfo.signature = signature.ToCharArray();
注意:
[csharp] view
plain copy
int size = Marshal.SizeOf(myInfo);
size=16+16+256
可见,获取到的非托管大小为288
但是,查看myInfo对象可以看到其实际大小如下所示:
问题:
这种实际大小和固定大小的不一致性,导致了在用Marshal类进行托管对象和非托管对象的转换时,会有如下错误提示:“未能封送类型,因为嵌入数组实例的长度与布局中声明的长度不匹配。”
解决办法还没想到......
小结:
MarshalAs这个属性很难用,很容易用错,用好需要对C#、C++和COM数据的布局方式有一定的了解才能做。所以做好使用一些工具来帮你,可以参照我下面的文章:
http://blog.csdn.net/Donjuan/archive/2009/02/05/3865026.aspx
如果你只是感兴趣的话,那就忘了这个属性吧,在.NET 4.0以后,微软会尽量解决掉这个属性。
相关文章推荐
- 操作复杂对象结构——访问者模式
- [转]操作复杂对象结构——访问者模式
- 操作复杂对象结构——访问者模式
- 企业数据库三层结构模型,MVC模式,设计模式,面向对象设计,接口规范及其他
- Delphi 的接口机制——接口操作的编译器实现过程(1)
- 异步调用WebService抛出ArgumentException"异步处理过程中出现错误。未完成的多个异步并发操作需要唯一的状态对象"
- 设计模式学习笔记二:面向对象基础四之抽象类和接口
- (已测试)在本地处理模式下将业务对象数据源与 ReportViewer Web 服务器控件一起使用
- 工厂模式定义:提供创建对象的接口
- FlyWeight 共享元对象结构模式
- 从代码到模式(二) 对象的结构和表现
- Reporting Services中通过主报表钻取到子报表再动态更改ReportViewer控件的reportPath时,提示错误对象的当前状态使该操作无效。
- 设计模式之桥接(Bridge)---对象结构性模式
- Gof设计模式之对象结构模式总结
- 模板方法模式(Template Method)-定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。
- Proxy 代理对象结构模式
- winform使用模式窗体,简单操作控件
- Visitor 表示一个作用于某个对象结构中的各元素的操作。它使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作
- 【开源】QuickPager 分页控件的内部结构,和OO原则与设计模式
- 在Hibernate中,持久化对象在被操作过程中可以分为三个时期