c++ buider xe4 动态调用DLL问题
XE4动态调用DLL出现错误:First chance exception at $00000000. Exception class $C0000005 with message 'access violation at 0x00000000: read of address 0x00000000'. Process can程序V1.exe (14428)确认是下面这个函数出现问题,麻烦请教下各位怎么解决谢谢了,折腾了几天了。
if(VCI_OpenDevice(nDeviceType,0,0)==0)
{
ShowMessage("打开CAN设备失败");
}
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include "mainwindow.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
int colect=0; //CAN启动标志位,0为未启动,1为启动成功
int colectnum=0;//取件装置在线个数
int nDeviceType;//CAN设备型号
//1.ZLGCAN系列接口卡信息的数据类型。
typedef struct _VCI_BOARD_INFO{
USHORThw_Version; //硬件版本
USHORTfw_Version; //固件版本
USHORTdr_Version; //驱动程序版本
USHORTin_Version; //接口库版本
USHORTirq_Num; //板卡使用中断号
BYTEcan_Num; //有几路CAN
CHARstr_Serial_Num[20]; //板卡序列号
CHARstr_hw_Type[40]; //硬件类型
USHORTReserved[4]; //保留参数
} VCI_BOARD_INFO,*PVCI_BOARD_INFO;
VCI_BOARD_INFO vciboardinfo;
//2.定义CAN信息帧的数据类型。
typedef struct _VCI_CAN_OBJ{
UINTID; //帧ID32位
UINTTimeStamp;//时间标识
BYTETimeFlag; //是否使用时间标识 为1有效
BYTESendType; //0正常发送 1单次发送 2自发自收 3 单次自发自收
BYTERemoteFlag;//是否是远程帧
BYTEExternFlag;//是否是扩展帧
BYTEDataLen; //数据长度
BYTEData[8]; //数据
BYTEReserved[3]; //保留
}VCI_CAN_OBJ,*PVCI_CAN_OBJ;
VCI_CAN_OBJ vcicanobj;
//3.定义CAN控制器状态的数据类型。
typedef struct _VCI_CAN_STATUS{
UCHARErrInterrupt; //中断操作 读操作会清除中断
UCHARregMode; //CAN控制器模式寄存器值
UCHARregStatus; //CAN控制器状态寄存器值
UCHARregALCapture;//仲裁丢失寄存器
UCHARregECCapture; //错误寄存器值
UCHARregEWLimit; //错误警告限制寄存器默认96
UCHARregRECounter;//接收错误寄存器值
UCHARregTECounter; //发送错误寄存器值
DWORDReserved; //保留
}VCI_CAN_STATUS,*PVCI_CAN_STATUS;
VCI_CAN_STATUS vcicanstatus;
//4.定义错误信息的数据类型。
typedef struct _ERR_INFO{
UINTErrCode; //错误码
BYTEPassive_ErrData[3];//消极错误
BYTEArLost_ErrData; //仲裁丢失错误
} VCI_ERR_INFO,*PVCI_ERR_INFO;
VCI_ERR_INFO vcierrinfo;
//5.定义初始化CAN的数据类型
typedef struct _INIT_CONFIG{
DWORDAccCode; //验收码
DWORDAccMask;//屏蔽码 0XFFFFFFFF全部接收
DWORDReserved;
UCHARFilter; //滤波方式 1为单滤波 0为双滤波
UCHARTiming0; // 波特率定时器
UCHARTiming1; // 波特率定时器
UCHARMode; //0为正常模式
}VCI_INIT_CONFIG,*PVCI_INIT_CONFIG;
VCI_INIT_CONFIG vciinitconfig;
//定义函数指针类型
//////////////////////////////////////////////////////////////////////////
typedef DWORD (CALLBACK* LPVCI_OpenDevice)(DWORD,DWORD,DWORD);
typedef DWORD (CALLBACK* LPVCI_CloseDevice)(DWORD,DWORD);
typedef DWORD (CALLBACK* LPVCI_InitCan)(DWORD,DWORD,DWORD,PVCI_INIT_CONFIG);
typedef DWORD (CALLBACK* LPVCI_ReadBoardInfo)(DWORD,DWORD,PVCI_BOARD_INFO);
typedef DWORD (CALLBACK* LPVCI_ReadErrInfo)(DWORD,DWORD,DWORD,PVCI_ERR_INFO);
typedef DWORD (CALLBACK* LPVCI_ReadCanStatus)(DWORD,DWORD,DWORD,PVCI_CAN_STATUS);
typedef DWORD (CALLBACK* LPVCI_GetReference)(DWORD,DWORD,DWORD,DWORD,PVOID);
typedef DWORD (CALLBACK* LPVCI_SetReference)(DWORD,DWORD,DWORD,DWORD,PVOID);
typedef ULONG (CALLBACK* LPVCI_GetReceiveNum)(DWORD,DWORD,DWORD);
typedef DWORD (CALLBACK* LPVCI_ClearBuffer)(DWORD,DWORD,DWORD);
typedef DWORD (CALLBACK* LPVCI_StartCAN)(DWORD,DWORD,DWORD);
typedef DWORD (CALLBACK* LPVCI_ResetCAN)(DWORD,DWORD,DWORD);
typedef ULONG (CALLBACK* LPVCI_Transmit)(DWORD,DWORD,DWORD,PVCI_CAN_OBJ,ULONG);
typedef ULONG (CALLBACK* LPVCI_Receive)(DWORD,DWORD,DWORD,PVCI_CAN_OBJ,ULONG,INT);
//////////////////////////////////////////////////////////////////////////
HINSTANCE m_hDLL;//用来保存打开的动态库句柄
//--------------接口函数指针-------------------------------------------------
LPVCI_OpenDevice VCI_OpenDevice;//打开CAN设备函数
LPVCI_CloseDevice VCI_CloseDevice; //关闭CAN设备函数
LPVCI_InitCan VCI_InitCAN; //初始化CAN
LPVCI_ReadBoardInfo VCI_ReadBoardInfo;//读取板卡信息
LPVCI_ReadErrInfo VCI_ReadErrInfo; //读取错误信息
LPVCI_ReadCanStatus VCI_ReadCanStatus; //读某一路CAN状态
LPVCI_GetReference VCI_GetReference; //读特殊设置信息
LPVCI_SetReference VCI_SetReference; //写特殊设置信息
LPVCI_GetReceiveNum VCI_GetReceiveNum;//读接收缓冲器帧数
LPVCI_ClearBuffer VCI_ClearBuffer; //清空接收缓冲区
LPVCI_StartCAN VCI_StartCAN; //启动某一路CAN
LPVCI_ResetCAN VCI_ResetCAN; //复位CAN
LPVCI_Transmit VCI_Transmit; //发送CAN帧
LPVCI_Receive VCI_Receive; //读取CAN帧
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
m_hDLL = LoadLibraryA("ControlCAN.dll");//打开动态连接库
//-------------------------------------------------------------获取函数地址---
VCI_OpenDevice=(LPVCI_OpenDevice)GetProcAddress(m_hDLL,"VCI_OpenDevice");
VCI_CloseDevice=(LPVCI_CloseDevice)GetProcAddress(m_hDLL,"VCI_CloseDevice");
VCI_InitCAN=(LPVCI_InitCan)GetProcAddress(m_hDLL,"VCI_InitCAN");
VCI_ReadBoardInfo=(LPVCI_ReadBoardInfo)GetProcAddress(m_hDLL,"VCI_ReadBoardInfo");
VCI_ReadErrInfo=(LPVCI_ReadErrInfo)GetProcAddress(m_hDLL,"VCI_ReadErrInfo");
VCI_ReadCanStatus=(LPVCI_ReadCanStatus)GetProcAddress(m_hDLL,"VCI_ReadCANStatus");
VCI_GetReference=(LPVCI_GetReference)GetProcAddress(m_hDLL,"VCI_GetReference");
VCI_SetReference=(LPVCI_SetReference)GetProcAddress(m_hDLL,"VCI_SetReference");
VCI_GetReceiveNum=(LPVCI_GetReceiveNum)GetProcAddress(m_hDLL,"VCI_GetReceiveNum");
VCI_ClearBuffer=(LPVCI_ClearBuffer)GetProcAddress(m_hDLL,"VCI_ClearBuffer");
VCI_StartCAN=(LPVCI_StartCAN)GetProcAddress(m_hDLL,"VCI_StartCAN");
VCI_ResetCAN=(LPVCI_ResetCAN)GetProcAddress(m_hDLL,"VCI_ResetCAN");
VCI_Transmit=(LPVCI_Transmit)GetProcAddress(m_hDLL,"VCI_Transmit");
VCI_Receive=(LPVCI_Receive)GetProcAddress(m_hDLL,"VCI_Receive");
//---------------------------------------------------------------------------
}
//---------------------------------------------------------------------------
void __fastcall TForm1::btn17Click(TObject *Sender)
{
Form2->ShowModal();//关于窗口
}
//---------------------------------------------------------------------------
void __fastcall TForm1::btn18Click(TObject *Sender)
{
Application->Terminate();//退出程序
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormCreate(TObject *Sender)
{
cbb1->Items->Clear();
cbb1->Items-> Add("USBCAN1"); //型号选择1USBCAN
cbb1->Items-> Add("PCI9820"); //型号选择29820
cbb1->ItemIndex=1;
cbb1->DropDownCount = cbb1->Items-> Count;
cbb2->Items->Clear();
cbb2->Items->Add("20k"); //波特率选择
cbb2->Items->Add("40k");
cbb2->Items->Add("80k");
cbb2->Items->Add("125k");
cbb2->Items->Add("250k");
cbb2->Items->Add("400k");
cbb2->Items->Add("800k");
cbb2->Items->Add("1000k");
cbb2->ItemIndex=4;
cbb2->DropDownCount=cbb2->Items->Count;
strngrd1->Cells[0][0]="序号";
strngrd1->Cells[1][0]="地址";
strngrd1->Cells[2][0]="下发命令";
strngrd1->Cells[3][0]="工作状态";
strngrd1->Cells[4][0]="工作内容";
strngrd1->Cells[5][0]="指示灯";
strngrd1->Cells[6][0]="取件数量";
strngrd1->Cells[7][0]="实际数量";
strngrd1->Cells[0][1]=0;
strngrd1->Cells[1][1]=0;
//--------------------------------------------CAN未启动取件装置不能操作------
edt1->Enabled=false;
btn3->Enabled=false;
btn4->Enabled=false;
btn5->Enabled=false;
edt2->Enabled=false;
btn6->Enabled=false;
btn7->Enabled=false;
btn8->Enabled=false;
btn9->Enabled=false;
btn10->Enabled=false;
btn11->Enabled=false;
edt3->Enabled=false;
btn12->Enabled=false;
btn13->Enabled=false;
btn14->Enabled=false;
//---------------------------------------------------------------------------
}
//---------------------------------------------------------------------------
void __fastcall TForm1::cbb1Change(TObject *Sender)
{
if (cbb1->Text=="USBCAN1") // 型号为USBCAN的时候不能选择通道
{
chk1->Checked=false;
chk2->Checked=false;
chk1->Enabled=false;
chk2->Enabled=false;
nDeviceType=3;
}
if(cbb1->Text=="PCI9820")
{
chk1->Enabled=true;
chk2->Enabled=true;
nDeviceType=5;
}
}
//---------------------------------------------------------------------------
void __fastcall TForm1::chk1Click(TObject *Sender)
{
if(chk1->Checked) //chk1和chk2只能同时选择一个(端口)
{
chk2->Enabled=false;
}
if(!chk1->Checked)
{
chk2->Enabled=true;
}
}
//---------------------------------------------------------------------------
void __fastcall TForm1::chk2Click(TObject *Sender)
{
if(chk2->Checked) //chk1和chk2只能同时选择一个 (端口)
{
chk1->Enabled=false;
}
if(!chk2->Checked)
{
chk1->Enabled=true;
}
}
//---------------------------------------------------------------------------
void __fastcall TForm1::tmr1Timer(TObject *Sender)
{
lst1->Items->Strings[0]=DateToStr(Date())+" "+TimeToStr(Time());
if(colect==0)
{
lst1->Items->Strings[1]="CAN设备未启动";
}
lst1->Items->Strings[2]="当前共有"+IntToStr(colectnum)+"个取件装置在线";
}
//---------------------------------------------------------------------------
void __fastcall TForm1::btn1Click(TObject *Sender)
{
if(VCI_OpenDevice(nDeviceType,0,0)==0)
{
ShowMessage("打开CAN设备失败");
}
}
//---------------------------------------------------------------------------