#c #visual-c #mfc #static #keyword
#c #visual-c #mfc #статический #ключевое слово
Вопрос:
объявление класса mydialog. ……………………… моя работа заключается в создании окна с кнопкой и текстовым полем, и когда я нажимаю эту кнопку в первый раз, будет создан поток, который будет выполнять чтение на выбранном порту, а для последующих данных в текстовом поле при нажатии кнопки он будет просто записывать в порт, а не создавать поток для чтения.
#include "resource.h"
class mydialog : public CDialog
{
DECLARE_DYNAMIC(mydialog)
public:
mydialog(CWnd* pParent = NULL); // standard constructor
virtual ~mydialog();
static HANDLE hSerial4;
static int loop_count;
// Dialog Data
enum { IDD = IDD_DIALOG1 };
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
DECLARE_MESSAGE_MAP()
public:
CString m_name;
afx_msg void OnBnClickedButton1();
BOOL OnInitDialog();
static UINT read_data(LPVOID hSerial);
// void read_data(HANDLE);
CString select_port;
};
cpreparationapp.cpp
………………………
#include "stdafx.h"
#include "mydialog.h"
class CPreparationApp : public CWinApp
{
public:
BOOL InitInstance();
};
BOOL CPreparationApp::InitInstance()
{
mydialog Dlg;
Dlg.DoModal();
m_pMainWnd = amp;Dlg;
return TRUE;
}
CPreparationApp theApp;
mydialog.cpp
……………………..
#include "stdafx.h"
#include "mydialog.h"
#include <windows.h>
#include <process.h>
// mydialog dialog
IMPLEMENT_DYNAMIC(mydialog, CDialog)
mydialog::mydialog(CWnd* pParent /*=NULL*/)
: CDialog(mydialog::IDD, pParent)
, m_name(_T(""))
, select_port(_T(""))
{
}
mydialog::~mydialog()
{
}
void mydialog::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
DDX_Text(pDX, IDC_EDIT1, m_name);
DDX_CBString(pDX, IDC_COMBO1, select_port);
}
BEGIN_MESSAGE_MAP(mydialog, CDialog)
ON_BN_CLICKED(IDC_BUTTON1, amp;mydialog::OnBnClickedButton1)
END_MESSAGE_MAP()
// mydialog message handlers
void mydialog::OnBnClickedButton1()
{
CEdit* abc=(CEdit*)GetDlgItem(IDC_EDIT1);
LPTSTR xyz123=new TCHAR[50];
CString text;
int k=abc->GetWindowTextA(xyz123,20);
CComboBox * pCombo=(CComboBox *)GetDlgItem(IDC_COMBO1);
int item = pCombo->GetCurSel();
if(item != CB_ERR)
{
pCombo->GetLBText(item,text);
}
TRACE("%sn",text);
loop_count ;
HANDLE hSerial;
if(loop_count==1)
{
hSerial = CreateFile(text,
GENERIC_WRITE | GENERIC_READ,
FILE_SHARE_READ | FILE_SHARE_WRITE,
0,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
0);
if(hSerial==INVALID_HANDLE_VALUE)
{
if(GetLastError()==ERROR_FILE_NOT_FOUND)
{
TRACE("serial port does not exist for writingn");
//serial port does not exist. Inform user.
}
TRACE("some other error,serial port does not exist for writingn");
//some other error occurred. Inform user.
}
DCB dcbSerialParams = {0};
dcbSerialParams.DCBlength=sizeof(dcbSerialParams);
if (!GetCommState(hSerial, amp;dcbSerialParams))
{
TRACE("error getting state for writingn");
//error getting state
}
dcbSerialParams.BaudRate=CBR_19200;
dcbSerialParams.ByteSize=8;
dcbSerialParams.StopBits=ONESTOPBIT;
dcbSerialParams.Parity=NOPARITY;
if(!SetCommState(hSerial, amp;dcbSerialParams))
{
TRACE("error setting state for writingn");
//error setting serial port state
}
COMMTIMEOUTS timeouts={0};
timeouts.ReadIntervalTimeout=50;
timeouts.ReadTotalTimeoutConstant=50;
timeouts.ReadTotalTimeoutMultiplier=10;
timeouts.WriteTotalTimeoutConstant=50;
timeouts.WriteTotalTimeoutMultiplier=10;
if(!SetCommTimeouts(hSerial, amp;timeouts))
{
TRACE("some error occured for writingn");
//error occureed. Inform user
}
mydialog::hSerial4=hSerial;
}
int n=100;
char szBuff1[100];
int m=0;
while(m<100 amp;amp; xyz123[m]!='')
{
szBuff1[m]=xyz123[m];
m ;
}
szBuff1[m]='';
DWORD dwByteswrote = 0;
if(!WriteFile(mydialog::hSerial4, szBuff1, n, amp;dwByteswrote, NULL))
{
TRACE("error writing n");
}
TRACE("%dn",dwByteswrote);
// mydialog Dlg1;
if(loop_count==1)
{
CWinThread *m_pThread;
m_pThread=AfxBeginThread(read_data,(LPVOID)hSerial);
}
}
UINT mydialog::read_data(LPVOID hSerial5)
{
HANDLE hSerial1=(HANDLE)hSerial5;
int n=100;
char szBuff[100];
DWORD dwBytesRead = 0;
if(!ReadFile(hSerial1, szBuff, n, amp;dwBytesRead, NULL))
{
TRACE("error reading n");
//error occurred. Report to user.
}
TRACE("%sn",szBuff);
// TRACE("%dn",dwBytesRead);
CloseHandle(hSerial1);
return 1;
}
BOOL mydialog::OnInitDialog()
{
// BOOL x;
mydialog dialog2;
HANDLE hSerial3;
CString temp,temp1;
int n=0;
CComboBox * pCombo=(CComboBox *)GetDlgItem(IDC_COMBO1);
pCombo->AddString("SAMPLE1");
pCombo->AddString("SAMPLE2");
for(n=0;n<9;n )
{
temp1.Format("%d",n);
temp="COM" temp1;
hSerial3 = CreateFile(temp,
GENERIC_WRITE | GENERIC_READ,
FILE_SHARE_READ | FILE_SHARE_WRITE,
0,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
0);
if(hSerial3==INVALID_HANDLE_VALUE)
{
TRACE("port not availablen");
}
else
{
pCombo->AddString(temp);
CloseHandle(hSerial3);
TRACE("port availablen");
}
}
// x=dialog2.check_open_port();
return CDialog::OnInitDialog();
}
Ответ №1:
Вы объявили статические члены в своем классе, но не определили их, поэтому вы получаете ошибки компоновщика.
Предоставьте определения вне тела класса
HANDLE mydialog::hSerial;
int mydialog::loop_count;
Комментарии:
1. Спасибо за ответ, у меня есть другой класс cpreparationapp, класс CPreparationApp: public CWinApp { public: BOOL InitInstance(); }; BOOL CPreparationApp::InitInstance() { mydialog Dlg; Dlg. DoModal(); m_pMainWnd = amp;Dlg; возвращает TRUE; } CPreparationApp TheApp; ТЕПЕРЬ, ПОСЛЕ ВЫПОЛНЕНИЯ ТОГО, ЧТО ВЫ СКАЗАЛИ, я ПОЛУЧАЮ ЭТУ общедоступную ОШИБКУ: static void * mydialog::hSerial» (?hSerial@mydialog @@2PAXA), уже определенную в CPreparationApp.obj
2. У вас есть две переменные, две переменные с одинаковым именем
hSerial
и двух разных типовHANDLE
иvoid*
в вашем проекте?3. я изменил это сейчас, даже тогда я получаю эти две ошибки mydialog.obj: ошибка LNK2005: «public: static void * mydialog:: hSerial4» (?hSerial4@mydialog @@2PAXA), уже определенные в CPreparationApp.obj 1> mydialog.obj : ошибка LNK2005: «public: static int mydialog::loop_count» (?loop_count@mydialog @@2HA) уже определены в CPreparationApp.obj 1>mydialog.obj : «public: static int mydialog::loop_count» (?loop_count@mydialog@@ определено в CPreparationApp.obj
4. @abhinav: Пожалуйста, опубликуйте полный код в своем вступительном сообщении и отформатируйте его соответствующим образом.