关于bcb调用dll

 由于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

两帖.

 

                    下载:http://download.csdn.net/source/2724379

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值