проблема с использованием статической переменной в vc mfc

#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: Пожалуйста, опубликуйте полный код в своем вступительном сообщении и отформатируйте его соответствующим образом.