由于XX原因,需要调用dll, dll是bcb6.0写的。多说无益,上码如下:
//---------------------------------------------------------------------------
#include <vcl.h>
#include <windows.h>
#pragma hdrstop
//---------------------------------------------------------------------------
// Important note about DLL memory management when your DLL uses the
// static version of the RunTime Library:
//
// If your DLL exports any functions that pass String objects (or structs/
// classes containing nested Strings) as parameter or function results,
// you will need to add the library MEMMGR.LIB to both the DLL project and
// any other projects that use the DLL. You will also need to use MEMMGR.LIB
// if any other projects which use the DLL will be performing new or delete
// operations on any non-TObject-derived classes which are exported from the
// DLL. Adding MEMMGR.LIB to your project will change the DLL and its calling
// EXE's to use the BORLNDMM.DLL as their memory manager. In these cases,
// the file BORLNDMM.DLL should be deployed along with your DLL.
//
// To avoid using BORLNDMM.DLL, pass string information using "char *" or
// ShortString parameters.
//
// If your DLL uses the dynamic version of the RTL, you do not need to
// explicitly add MEMMGR.LIB as this will be done implicitly for you
//---------------------------------------------------------------------------
#pragma argsused
int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void* lpReserved)
{
return 1;
}
//---------------------------------------------------------------------------
HANDLE hCom;
extern "C" __declspec(dllexport)
bool __stdcall Connect(AnsiString WhichCom,AnsiString BaudRate)
{
__int32 nBaudRate;
__int16 nTimeLapse;
__int8 nTimeInter,nParity,nDtrControl;
int fsuccess;
char c_comport[10];
DCB Dcb;
COMMTIMEOUTS Timeouts;
// GetPrivateProfileString("CompileCardCom","ComPort","COM1",c_comport,8,"./config.ini");
// nBaudRate =GetPrivateProfileInt("CompileCardCom","BaudRate_card",9600,"./config.ini");
// nTimeLapse =GetPrivateProfileInt("CompileCardCom","ReadTotalTimeoutConstant_card",600,"./config.ini");
// nTimeInter =GetPrivateProfileInt("CompileCardCom","ReadIntervalTimeout_card",10,"./config.ini");
// nParity =GetPrivateProfileInt("CompileCardCom","Parity_card",0,"./config.ini");
// nDtrControl=GetPrivateProfileInt("CompileCardCom","fDtrControl_card",1,"./config.ini");
strcpy(c_comport,WhichCom.c_str());
nBaudRate = StrToInt(BaudRate);
nTimeLapse =600;
nTimeInter =20;;
nParity =0;
nDtrControl=1;
hCom=CreateFile(c_comport,
GENERIC_READ|GENERIC_WRITE,
0,
NULL,
OPEN_EXISTING,
0,
NULL);
//communicate fail(comport cann't open),return 4
if (hCom==INVALID_HANDLE_VALUE)
{
CloseHandle(hCom);
ShowMessage("打开通讯口失败");
return false;
}
fsuccess=SetupComm(hCom,512,512);
if (fsuccess==0)
{
CloseHandle(hCom);
AnsiString s_Message="设置通讯口"+AnsiString(c_comport)+"缓存信息失败";
ShowMessage(s_Message.c_str());
return false;
}
fsuccess=GetCommState(hCom,&Dcb);
if (fsuccess==0)
{
CloseHandle(hCom);
ShowMessage("取通讯口状态信息失败");
return false;
}
Dcb.BaudRate=nBaudRate; //baud rate
Dcb.ByteSize=8;
switch (nParity)
{
case 1:
Dcb.Parity = EVENPARITY;
break;
case 2:
Dcb.Parity = ODDPARITY;
break;
case 3:
Dcb.Parity = MARKPARITY;
break;
default:
Dcb.Parity = NOPARITY;
break;
}
Dcb.StopBits=ONESTOPBIT;
switch (nDtrControl)
{
case 1:
Dcb.fDtrControl=DTR_CONTROL_ENABLE;
break;
case 2:
Dcb.fDtrControl=DTR_CONTROL_HANDSHAKE;
break;
default:
Dcb.fDtrControl=DTR_CONTROL_DISABLE;
}
fsuccess=SetCommState(hCom,&Dcb);
if (fsuccess==0)
{
CloseHandle(hCom);
ShowMessage("设置通讯口状态信息失败");
return false;
}
fsuccess=GetCommTimeouts(hCom,&Timeouts);
if (fsuccess==0)
{
CloseHandle(hCom);
ShowMessage("取通讯口时间信息失败");
return false;
}
if (nTimeInter > 0)
Timeouts.ReadIntervalTimeout = nTimeInter;
Timeouts.ReadTotalTimeoutConstant=nTimeLapse;
Timeouts.ReadTotalTimeoutMultiplier=0;
Timeouts.WriteTotalTimeoutMultiplier=0;
Timeouts.WriteTotalTimeoutConstant=nTimeLapse;
fsuccess=SetCommTimeouts(hCom,&Timeouts);
if (fsuccess==0)
{
CloseHandle(hCom);
ShowMessage("设置通讯口时间信息失败");
return false;
}
return true;
}
extern "C" __declspec(dllexport)
bool __stdcall Disconnect()
{
bool succ;
if (hCom == INVALID_HANDLE_VALUE)
return false;
succ = CloseHandle(hCom);
if (!succ)
{
ShowMessage("关闭通讯口出错");
return false;
}
return true;
}
extern "C" __declspec(dllexport)
char * __stdcall sreadkhNew(AnsiString s_Command)
{
Byte vb1,BufferOut[20],BufferIn[40];
int ii,ijk;
int fsuccess;
short nPartNo,nMassNo,nTempUse ;
AnsiString s_Constant="0123456789ABCDEF";
AnsiString s_TempUse,s_Return;
DWORD Num;
fsuccess=PurgeComm(hCom,PURGE_RXCLEAR|PURGE_TXCLEAR);
if (fsuccess==0)
{
ShowMessage("清除通讯口输入缓冲区出错");
return "04";
}
Num=0;
memset(BufferIn,0x00,16); //接收缓冲区
s_TempUse=Trim(s_Command);
nPartNo=(s_Constant.AnsiPos(s_TempUse.SubString(1,1))-1)*16+(s_Constant.AnsiPos(s_TempUse.SubString(2,1))-1); //区号
nMassNo=(s_Constant.AnsiPos(s_TempUse.SubString(3,1))-1)*16+(s_Constant.AnsiPos(s_TempUse.SubString(4,1))-1); //块号
BufferOut[0] = 0xc3; //发送读用户卡命令
BufferOut[1] = nPartNo;
BufferOut[2] = nMassNo;
fsuccess=WriteFile(hCom,BufferOut,3,&Num,NULL);
if (fsuccess==0 || Num!=3)
{
return "04-03";
}
fsuccess=ReadFile(hCom,BufferIn,16,&Num,NULL);
if (fsuccess==0 || Num!=16)
{
return "04-16";
}
if (BufferIn[0]==0 && BufferIn[1]==0 && BufferIn[2]==0 && BufferIn[3]==0)
{
return "04-00";
}
s_Return="";
for(ii=0;ii<8;ii++) //16个字节,32个字符
{
ijk=BufferIn[ii] & 0xff;
s_Return=s_Return+s_Constant.SubString(ijk/16+1,1)+s_Constant.SubString(ijk%16+1,1);
}
return s_Return.c_str();
}
extern "C" __declspec(dllexport)
bool __stdcall swritekhNew(char* s_SendDataP,char* PartNoP,char* MassNoP)
{
byte BufferOut[40],BufferIn[40];
int ii,jj,kk;
int fsuccess;
int iPartNo,iMassNo;
DWORD Num;
AnsiString s_constant="0123456789ABCDEFabcdef";
AnsiString s_SendData,PartNo,MassNo;
s_SendData=AnsiString(s_SendDataP);
PartNo=AnsiString(PartNoP);
MassNo=AnsiString(MassNoP);
fsuccess=PurgeComm(hCom,PURGE_RXCLEAR|PURGE_TXCLEAR);
if (fsuccess==0)
{
ShowMessage("清除通讯口输入缓冲区出错");
return 4;
}
memset(BufferOut,0x00,40);
Num=0;
BufferOut[0]=0xc5; //写用户卡命令
for (ii=1;ii<16;ii++) //将字符串转换为BCD码
{
jj=(s_constant.AnsiPos(s_SendData.SubString(ii*2-1,1)))-1;
kk=(s_constant.AnsiPos(s_SendData.SubString(ii*2,1)))-1;
if (jj>15)
jj=jj-6;
if (kk>15)
kk=kk-6;
if (jj<0 || kk<0)
{
ShowMessage("往个人卡卡片写的数据有错,数据非有效二进制数");
return 4;
}
BufferOut[ii]=jj*16 +kk;
}
iPartNo=StrToInt("0x"+PartNo);iMassNo=StrToInt("0x"+MassNo);
BufferOut[17] =iPartNo; // 区号
BufferOut[18] =iMassNo; // 块号
BufferOut[19]=0;
for (ii=1;ii<18;ii++) //计算校验和
BufferOut[19]=BufferOut[ii]+BufferOut[19];
fsuccess=WriteFile(hCom,BufferOut,20,&Num,NULL);
if (fsuccess==0 || Num!=20)
{
return 4;
}
fsuccess=ReadFile(hCom,BufferIn,1,&Num,NULL);
if (fsuccess==0)
{
return 4;
}
if (BufferIn[0]!=0x5c)
{
return 7;
}
return true;;
}
//*********************************************************
//读取
//********************************************
extern "C" __declspec(dllexport)
AnsiString __stdcall sreadkh()
{
Byte vb1,BufferOut[16],BufferIn[16];
int ii,ijk;
int fsuccess;
AnsiString s_Constant="0123456789ABCDEF";
AnsiString s_Return;
DWORD Num;
fsuccess=PurgeComm(hCom,PURGE_RXCLEAR|PURGE_TXCLEAR);
if (fsuccess==0)
{
ShowMessage("清除通讯口输入缓冲区出错");
return "04";
}
Num=0;
memset(BufferIn,0x00,16);
BufferOut[0] = 0x01; //发送读用户卡命令
fsuccess=WriteFile(hCom,BufferOut,1,&Num,NULL);
if (fsuccess==0 || Num!=1)
{
return "04";
}
fsuccess=ReadFile(hCom,BufferIn,8,&Num,NULL);
if (fsuccess==0 || Num!=8)
{
return "04";
}
//计算校验和
ijk=0;
vb1=BufferIn[0];
for (ii=1;ii<7;ii++)
vb1=vb1+BufferIn[ii];
if (vb1!=BufferIn[7])
{
return "04";
}
if (BufferIn[0]==0 && BufferIn[1]==0 && BufferIn[2]==0 && BufferIn[3]==0)
{
return "04";
}
s_Return="";
for(ii=0;ii<8;ii++) //8个字节,16个字符
{
ijk=BufferIn[ii] & 0xff;
s_Return=s_Return+s_Constant.SubString(ijk/16+1,1)+s_Constant.SubString(ijk%16+1,1);
}
return s_Return;
}
就4个函数:打开关闭串口。读写m1卡,在bcb,和c#下面分别调用.
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
extern "C" __declspec(dllimport)
bool __stdcall Connect(AnsiString WhichCom,AnsiString BaudRate);
extern "C" __declspec(dllimport)
bool __stdcall Disconnect();
extern "C" __declspec(dllimport)
char* __stdcall sreadkhNew(AnsiString s_Command);
extern "C" __declspec(dllimport)
bool __stdcall swritekhNew(AnsiString s_SendData,AnsiString PartNo,AnsiString MassNo);
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
bool b;
b=Connect("Com4","9600");
if (b)
ShowMessage("串口打开成功");
else
ShowMessage("失败");
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button2Click(TObject *Sender)
{
bool b;
b=Disconnect();
if (b)
ShowMessage("串口关闭成功");
else
ShowMessage("失败");
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button3Click(TObject *Sender)
{
char* ss;
ss=sreadkhNew("0200");
ShowMessage(AnsiString(ss));
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button4Click(TObject *Sender)
{
AnsiString ss;
bool b;
ss="680000539000004B0000000000000000"; //32位
b=swritekhNew("680000539000004B0000000000000000","02","00");
if (b)
ShowMessage("写卡成功");
else
ShowMessage("失败");
}
//---------------------------------------------------------------------------
c#的调用:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;
namespace WindowsFormsApplication3
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private class Project2
{
//定义DLL文件名,此文件路径要加到系统Path中
private const string _fileDll = @"Project2.dll";
[DllImport(_fileDll, EntryPoint = "Connect", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
public static extern bool Connect(StringBuilder WhichCom, StringBuilder BaudRate);
[DllImport(_fileDll, EntryPoint = "Disconnect", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
public static extern bool Disconnect();
//C#中的申明
[DllImport(_fileDll, EntryPoint = "sreadkhNew", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
public static extern StringBuilder sreadkhNew(StringBuilder s_Command);
[DllImport(_fileDll, EntryPoint = "swritekhNew", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
public static extern bool swritekhNew(StringBuilder s_SendData, StringBuilder PartNo, StringBuilder MassNo);
}
private void button1_Click(object sender, EventArgs e)
{
bool b;
StringBuilder WhichCom = new StringBuilder();
WhichCom.Append("Com4");
StringBuilder BaudRate = new StringBuilder();
BaudRate.Append("9600");
b = Project2.Connect(WhichCom, BaudRate);
if (b)
MessageBox.Show("串口打开成功");
else
MessageBox.Show("串口打开失败");
}
private void button2_Click(object sender, EventArgs e)
{
bool b;
b = Project2.Disconnect();
if (b)
MessageBox.Show("串口关闭成功");
else
MessageBox.Show("串口关闭失败");
}
private void button3_Click(object sender, EventArgs e)
{
String ss;
StringBuilder s_Command = new StringBuilder();
s_Command.Append("0200");
ss = Project2.sreadkhNew(s_Command).ToString();
MessageBox.Show(ss);
}
private void button4_Click(object sender, EventArgs e)
{
bool b;
StringBuilder s_SendData = new StringBuilder();
s_SendData.Append("680000539000004B0000000000000000");
StringBuilder PartNo = new StringBuilder();
PartNo.Append("02");
StringBuilder MassNo = new StringBuilder();
MassNo.Append("00");
b = Project2.swritekhNew(s_SendData, PartNo, MassNo);
if (b)
MessageBox.Show("写卡成功");
else
MessageBox.Show("失败");
}
}
}
调用delphi参见http://topic.csdn.net/u/20100723/16/74b15b82-df97-4420-872a-c990d1fc838d.html
http://topic.csdn.net/u/20100528/16/6ac8563f-54c3-492d-97ca-dee01c93073b.html
两帖.