读书人

关于C#调用VC++6.0 DLL的有关问题

发布时间: 2012-04-11 17:42:33 作者: rapoo

关于C#调用VC++6.0 DLL的问题
原始dll声明如下:
dll调用(posinf.dl)函数名为:int bankall (char * request,char *response),其中第一个参数为传入参数。
ocx调用(umsocx.ocx):trans(),传入参数为:bankrequest
请求参数格式说明如下:
内容格式长度描述
POS机号ANS8不足右补空格
POS员工号ANS8不足右补空格
交易类型标志N2'00'-消费 '01'-撤消
'02'-退货 '03'-查余额
'04'-重打印 '05'-签到
'06'-结算 '07'-重打结算单
'08'-全民付 '55'-换班统计
'10'-积分消费 '11'-积分撤消
'12'-分期消费 '13'-分期撤销
'21'-'26':预授权类交易
金额N12信用卡消费金额,char(12),没有小数点".",精确到分,最后两位为小数位,不足左补0。
原交易日期N8yyyymmdd格式,退货时用,其他交易空格
原交易参考号N12退货时用,其他交易空格
原凭证号N6撤消时用,其他交易空格
LRC校验ANS33位随机数字

dll调用(posinf.dl)函数名为:int bankall (char * request,char *response),其中第二个参数为应答参数。
ocx调用函数名为:trans(),传入参数为:BankResponse
应答参数格式说明如下:
内容格式长度描 述
返回码N200 表示成功,其它表示失败
银行行号N4发卡行代码
卡号N20卡号(屏蔽部分,保留前6后4)
凭证号N6
金额N12
错误说明ANS40中文解释
商户号N15
终端号N8
批次号N6
交易日期N4
交易时间N6
交易参考号N12
授权号N6
清算日期N4
LRC校验ANS3三位数字,应该和请求一致

--------------------------------------
使用以下C#代码调用时总出现System.AccessViolationException: 尝试读取或写入受保护的内存。这通常指示其他内存已损坏。
C#代码如下:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;

namespace WindowsApplication1
{
public partial class Form1 : Form
{
[DllImport(@"posinf.dll", CallingConvention = CallingConvention.Cdecl, SetLastError = true, CharSet = CharSet.Ansi, EntryPoint = @"bankall")]
static extern int bankall(string request, out string response);//尝试过使用byte[],char[],StringBuilder以及ref修饰符均未解决问题。CallingConvention.stdcall也尝试过。

public Form1()
{
InitializeComponent();
}

private void button1_Click(object sender, EventArgs e)
{

string str = null;
int p = -9;
string ss = "";

ss = ss.PadLeft(148, ' ');
str = "POS12345";
str += "USER1234";
str += "02";
str += "000000005000";
str += "20120302";
str += "172900123456";
str += " ";
str += "325";



p=Form1.bankall(str,out ss);
this.textBox1.Text = ss.ToString();
this.Text = p.ToString();
}
}
}

[解决办法]
刚想到一个问题,C++的字符串以'\0'作为结束标识,使用StringBuilder须保证response的内容内无0x00,否则固定长度缓冲区应使用Byte[](同样不需要out或者ref,但调用前要使用new创建足够大的数组)

读书人网 >C#

热点推荐