안녕하세요. Visual C++ (2019)로 프로그램을 짜다가 막히는 부분이 있어서 질문드립니다.
MFC 윈도우 창이 존재하고, 프로그램 외부로 통신하는 독립 클래스가 존재합니다. 이 클래스에서는 스레드가 2개 수행되고,
외부에서 입력이 있으면 MFC 윈도우의 리스트박스에 입력이 있었다는 걸 출력하고 싶습니다.
void Ctest01Dlg::PrintInfoWithTime(std::string msg) {
std::string newMsg = NowToString() + " : " + msg;
lbox.InsertString(0, newMsg.c_str());
}
/* Server.h */
class Server {
public:
zmq::context_t ctx;
zmq::socket_t router;
Ctest01Dlg * pDlg = (Ctest01Dlg *)AfxGetMainWnd();
std::thread threadBrokerSender;
void StartThreadReceiver() { threadBrokerReceiver = std::thread([this] { TrdReceiveRequest(); }); }
void TrdReceiveRequest() {
while (true) {
zmq::message_t requestMsg;
router.recv(requestMsg, zmq::recv_flags::none);
std::string str_msg = requestMsg.to_string();
if (str_msg == "req") {
pDlg->PrintInfoWithTime("REQ");
}
대략적인 구조는 위와 같습니다. 컴파일까지는 되는데, 실행해 보면 <읽기 액세스 위반입니다. this->pDlg이(가) nullptr였습니다.>
와 같은 에러 메세지가 나옵니다. Ctest01Dlg * pDlg 부분을 삭제하면 잘 작동됩니다.
AfxBeginThread로도 다른 내부 메소드 스레드를 만들었는데, 이것도 마찬가지로 pDlg->Method(); 형태로는 사용이 안 돼서
pDlg->PostMessageA 형태로 사용하고 있습니다.
인터넷에 찾아 보니까 외부 클래스에서 이런 방식으로 다이얼로그에 접근이 된다고 나오는데, 제가 어디서 잘못 이해한 건지 잘 모르겠습니다. 아시는 분이 계시면 도움 말씀 부탁드립니다.
참고하십시요.
https://github.com/christopherpow/nesicide/blob/8e4d1b6ed91e23cff21f47071450da6eb66e1176/common/cqtmfc.h#L4262
https://learn.microsoft.com/en-us/cpp/mfc/reference/cwnd-class?view=msvc-170
https://i.imgur.com/lUwZoLI.jpg
class Ctest01Dlg : public CDialogEx
{
public:
Ctest01Dlg(CWnd* pParent = nullptr);
이렇게 정의돼 있습니다. 찾아보니까 CDialogEx는 CWnd를 상속받는 클래스로 나오는데, 이 차이 때문에 접근 방법도 달라져야 하나요?
알려주신 키워드로 인터넷을 찾아보다, 위의 이미지처럼 다이얼로그를 초기화할 때 전역변수로 참조시키는 방법을 찾아냈습니다. 혹시 전역변수를 사용하지 않고, 보여 주신 예처럼 바로 클래스 안에서 다이얼로그를 참조하는 방법도 있을까요?
https://github.com/christopherpow/nesicide/blob/8e4d1b6ed91e23cff21f47071450da6eb66e1176/common/cqtmfc.h#L3870