关于C#调用VC++6.0 DLL的问题
原始dll声明如下:
dll调用(posinf.dl)函数名为:int bankall (char * request,char *response),其中第一个参数为传入参数。
ocx调用(umsocx.ocx):trans(),传入参数为:bankrequest
请求参数格式说明如下:
内容	格式	长度	描述
POS机号	ANS	8	不足右补空格
POS员工号	ANS	8	不足右补空格
交易类型标志	N	2	'00'-消费        '01'-撤消
'02'-退货        '03'-查余额
'04'-重打印      '05'-签到
'06'-结算        '07'-重打结算单
'08'-全民付      '55'-换班统计
'10'-积分消费        '11'-积分撤消
'12'-分期消费        '13'-分期撤销
'21'-'26':预授权类交易
金额	N	12	信用卡消费金额,char(12),没有小数点".",精确到分,最后两位为小数位,不足左补0。
原交易日期	N	8	yyyymmdd格式,退货时用,其他交易空格
原交易参考号	N	12	退货时用,其他交易空格
原凭证号	N	6	撤消时用,其他交易空格
LRC校验	ANS	3	3位随机数字
dll调用(posinf.dl)函数名为:int bankall (char * request,char *response),其中第二个参数为应答参数。
ocx调用函数名为:trans(),传入参数为:BankResponse
应答参数格式说明如下:
内容	格式	长度	描   述
返回码	N	2	00 表示成功,其它表示失败
银行行号	N	4	发卡行代码
卡号	N	20	卡号(屏蔽部分,保留前6后4)
凭证号	N	6	
金额	N	12	
错误说明	ANS	40	中文解释
商户号	N	15	
终端号	N	8	
批次号	N	6	
交易日期	N	4	
交易时间	N	6	
交易参考号	N	12	
授权号	N	6	
清算日期	N	4	
LRC校验	ANS	3	三位数字,应该和请求一致
--------------------------------------
使用以下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创建足够大的数组)