我做了一個界面,通過界面按鈕向作業執行緒發送結構體資料(就是位置坐標)。作業執行緒接收到資料,將資料通過TCPIP協議發送到樹莓派,同時樹莓派將采集到的資料通過TCPIP協議發送到作業執行緒,作業執行緒再將資料顯示主界面
uj5u.com熱心網友回復:
PostThreadMessage ?uj5u.com熱心網友回復:
共享記憶體或者視圖PostThreadMessage,如果使用前者,要注意同步uj5u.com熱心網友回復:
typedef struct MoveCmd // 坐標命令結構體但是使用PostThreadMessageA 函式只是執行訊息處理函式,那怎么把資料傳送到作業執行緒執行函式中去。
{
float position_x;
float position_y;
int execute_cmd[512];
} MoveCmd;
MoveCmd *moveCmd;
::PostThreadMessageA(m_pThread->m_nThreadID,WM_CMD_MSG,0,0);
LRESULT CMFC_TCP_IPDlg::TransCommand(WPARAM wParam, LPARAM lParam) // 訊息回應函式
{
}
UINT ThreadFunction(LPVOID pParam);
{
}
高手能說的詳細點嗎
uj5u.com熱心網友回復:
我想通過按鈕更新 作業執行緒中的資料uj5u.com熱心網友回復:
全域變數 靜態變數 共享記憶體 管道 ……
uj5u.com熱心網友回復:
以前做下載進度顯示用的是全域變數,反正能實作。不過總感覺用全域變數不太好
uj5u.com熱心網友回復:
Multiple Threads in the User Interface http://msdn.microsoft.com/zh-cn/library/ms810439.aspxuj5u.com熱心網友回復:
SetEvent + WaitForSingleObject ?uj5u.com熱心網友回復:
unsigned int CMFC_TCP_IPDlg::Server_Thread(LPVOID pParam){
CMFC_TCP_IPDlg *pDlg = (CMFC_TCP_IPDlg *)pParam; // 將執行緒指標強制轉化為CMFC_TCP_IPDlg型別指標
MSG msg;
// tagRun=0;
// 將發送緩沖區和接識訓沖區清零
memset(sendBuf,0,sizeof(sendBuf));
memset(recvBuf,0,sizeof(recvBuf));
/********************************************************************************************/
struct MoveCmd *cmdData=https://bbs.csdn.net/topics/new(MoveCmd); // 執行緒要處理的資料
memset(cmdData,0,sizeof(cmdData));
while(::PeekMessageA(&msg,NULL,0,0,PM_REMOVE))
{
switch(msg.message)
{
case WM_QUIT://退出從執行緒
break;
ExitThread(10);
case WM_CMD_MSG:
// AfxMessageBox("接收訊息成功");
cmdData = (MoveCmd*)msg.wParam;
break;
default:
break;
}
}
/***************************************** 加載套接字庫************************************/
WORD wVersion; // 存盤套接字版本
wVersion=MAKEWORD(1,1); // 保存WinSock庫版本號。不是C++標準的型別,是微軟SDK中的型別,WORD的意思為字,是2byte(16位)的無符號整數,表示范圍0~65535.
WSADATA wsaData; //存放windows socket初始化資訊
WSAStartup(wVersion,&wsaData); //加載套接字庫,成功回傳0
if(LOBYTE(wsaData.wVersion)!=1||HIBYTE(wsaData.wVersion)!=1) //判斷wsaData.wVersion低位元組和高位元組是否都為1,若版本不對應,呼叫WSACleanup函式終止對Socket的使用
{
WSACleanup();
}
//-------創建用于監聽的套接字-----------//
if ((sockSrv = socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET) // 創建通信端點: sockSrv 回傳套接字描述符
{
::SetWindowText(::GetDlgItem(pDlg->m_hWnd, IDC_EDIT2), "創建監聽套接字失敗");
}
else
{
::SetWindowText(::GetDlgItem(pDlg->m_hWnd, IDC_EDIT2), "創建監聽套接字成功"); // 獲得視窗的句柄
}
//--------系結套接字----------//
SOCKADDR_IN addrSrv; // 服務器端地址結構體變數 typedef sockaddr_in SOCKADDR_IN
memset(&addrSrv,0,sizeof(addrSrv)); // 清空結構體
addrSrv.sin_addr.S_un.S_addr=htonl(INADDR_ANY); // //將IP地址指定為INADDR_ANY,允許套接字向任何分配給本地機器的IP地址發送或接收資料。當有多個網卡多個IP,使用INADDR_ANY可以簡化編程
// addrSrv.sin_addr.S_un.S_addr=inet_addr(serverIP); //系結本地IP
addrSrv.sin_family=AF_INET; // 設定家族簇
addrSrv.sin_port=htons(Port_num); // 系結埠號
// addrSrv.sin_zero[8]=0;
/* 捆綁sockfd描述符 指定本地地址──bind() 當一個套接字用socket()創建后,存在一個名字空間 (地址族), 但它沒有被命名。bind()將套接字地址(包括 本地主機地址和本地埠地址)與所創建的套接字號 聯系起來,即將名字賦予套接字,以指定本地半相關。 */
if(SOCKET_ERROR==bind(sockSrv,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR)))
{
::SetWindowText(::GetDlgItem(pDlg->m_hWnd, IDC_EDIT2), "系結錯誤");
}
else
{
// ::SetWindowText(::GetDlgItem(pDlg->m_hWnd, IDC_EDIT2), "系結成功");
pDlg->SetDlgItemText(IDC_EDIT2,"系結成功");
}
//-------將套接字設為監聽模式,準備接收客戶端請求------- //
listen(sockSrv,2); //引數(套接字描述符,backlog這里是2(等待連接佇列的最大長度))
//用來接收客戶端的地址資訊
SOCKADDR_IN addrClient; // typedef sockaddr_in addrClient
memset(&addrClient,0,sizeof(addrClient)); // 清空結構體
int iaddrSize=sizeof(SOCKADDR); // 對accept的第三個函式來說,在呼叫之前必須為它賦予一個初始值,即SOCKADDR_IN
// while(1)
// {
sockConn = accept(sockSrv, (struct sockaddr *)&addrClient, &iaddrSize);
if ( sockConn==INVALID_SOCKET ) // WSASetLastError()
{
::SetWindowText(::GetDlgItem(pDlg->m_hWnd, IDC_EDIT2), "未連接到客戶端");
char err[128];
itoa(INVALID_SOCKET ,err,10);
::SetWindowText(::GetDlgItem(pDlg->m_hWnd, IDC_EDIT4), itoa(INVALID_SOCKET,err,10));
}
else
{
// ::SetWindowText(::GetDlgItem(pDlg->m_hWnd, IDC_EDIT2), "已連接客戶端");
pDlg->SetDlgItemText(IDC_EDIT3,"已連接客戶端");
}
//******************* 發送資料********************//
memset(moveCmd,0,sizeof(MoveCmd)); // 清空moveCmd結構體
// 結構體賦值
moveCmd->position_x=200.0;
moveCmd->position_y=400.0;
memcpy(sendBuf,moveCmd,sizeof(MoveCmd));
nSize=send(sockConn,sendBuf,100,0); // 注意發送和接受的第一個引數:應該是accept()回傳的客戶端的套接字描述符
if(-1==nSize)
{
::SetWindowText(::GetDlgItem(pDlg->m_hWnd, IDC_EDIT8), "發送資料失敗");
}
else
{
char err[128];
itoa(nSize ,err,10);
::SetWindowText(::GetDlgItem(pDlg->m_hWnd, IDC_EDIT8), itoa(nSize,err,10));
}
// ::SetWindowText(::GetDlgItem(pDlg->m_hWnd, IDC_EDIT4), sendBuf);
// ::PostMessage(pDlg->m_hWnd, WM_CMD_MSG, 0, 0);
//******************* 接收資料********************//
int recv_size= recv(sockConn,recvBuf,strlen(recvBuf)+1,0);
if(SOCKET_ERROR==recv_size)
{
::SetWindowText(::GetDlgItem(pDlg->m_hWnd, IDC_EDIT3), "接收錯誤");
char err[128];
itoa(SOCKET_ERROR ,err,10);
::SetWindowText(::GetDlgItem(pDlg->m_hWnd, IDC_EDIT7), itoa(SOCKET_ERROR,err,10));
}
else
{
::SetWindowText(::GetDlgItem(pDlg->m_hWnd, IDC_EDIT4), recvBuf);
}
我與客戶端連接成功了,但是我發送的資料為什么顯示發送失敗呢,接收資料也是那樣,我檢查了好幾天,都沒把問題解決,麻煩高手指導一下
uj5u.com熱心網友回復:
雖然我不太懂,但是我
推薦一個講的特別好的:https://blog.csdn.net/qq61394323/article/details/25334293按照這個做應該沒有太大問題
uj5u.com熱心網友回復:
把視窗指標直接傳到執行緒里面不就行了uj5u.com熱心網友回復:
據說,執行緒開啟的時候,把視窗的指標也傳過去,那么執行緒就可以直接訪問視窗的變數uj5u.com熱心網友回復:
iocp訊息佇列?uj5u.com熱心網友回復:
在執行緒創建初就把類實體句柄傳進去不就好了嗎,之后再執行緒回圈中直接讀類物件的屬性或呼叫類函式就可以得到相關東西啦。比如創建執行緒時傳遞個this進去
...
this->m_threadhandle = CreateThread(&thread_sa,0,(LPTHREAD_START_ROUTINE)OnConnectThread,(LPVOID)this,0,&(this->m_threadid));
...
然后在執行緒里可以重現類物件,如
DWORD SKTCPClient::OnConnectThread(LPVOID pParam)
{
SKTCPClient *obj_this = (SKTCPClient *)pParam;
int m_socket = obj_this->getSocket();
//...
return 0;
}
uj5u.com熱心網友回復:
使用快取佇列uj5u.com熱心網友回復:
作業者 執行緒 無 訊息佇列 !uj5u.com熱心網友回復:
postmessage是作業執行緒向主執行緒發送訊息,主執行緒向作業執行緒發送訊息模仿postmessage即可了,給一個標記位,作業執行緒監聽這個標記位即可,另外樹莓派用在工業上差了點吧?uj5u.com熱心網友回復:
主執行緒向作業執行緒發送訊息用 Eventuj5u.com熱心網友回復:
if (BytesWritten>0){ // writting OK tell main to show
ResetEvent(pDload->m_hPostEventWrite);// first reset
BOOL posted=pDload->PostMessage(WM_COMMNOTIFY,
(WPARAM)1, // "WatchWrite"
MAKELONG(BytesWritten,BlockCount));
// wait answer
WaitForSingleObject(pDload->m_hPostEventWrite,0xFFFFFFFF);
}
uj5u.com熱心網友回復:
我猜想你是做多機器人專案,我也是做這個的,用UDP通訊,實作方法是在執行緒中直接訪問主行程,this->x = theApp.ui.x; 要注意執行緒同步和執行緒互斥。轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/15255.html
標籤:界面
