问题
I have this structure:
typedef struct tagCOPY_PACKET
{
TCHAR szFile[_MAX_PATH];
GUID guidSignature;
} S_COPY_PACKET;
I prepare to send data with WM_COPYDATA
like this:
CString strFile = GetFileToOpenFromFileExplorerPath();
S_COPY_PACKET sCopyDataPacket;
_tcscpy_s(sCopyDataPacket.szFile, _MAX_PATH, strFile);
sCopyDataPacket.guidSignature = CopyData_Signature;
COPYDATASTRUCT cds;
cds.dwData = COPYDATA_TYPE_MSA;
cds.cbData = sizeof(sCopyDataPacket);
cds.lpData = &sCopyDataPacket;
DWORD_PTR dwResult;
if (SendMessageTimeout(hOtherInstance, WM_COPYDATA,
NULL, (LPARAM)(LPVOID)&cds, SMTO_BLOCK, 2000, &dwResult) != 0)
{
}
And at the other end:
BOOL CMeetingScheduleAssistantDlg::OnCopyData(CWnd* pWnd, COPYDATASTRUCT* pCopyDataStruct)
{
if (pCopyDataStruct->dwData == COPYDATA_TYPE_MSA)
{
S_COPY_PACKET* pCopyPacket = (S_COPY_PACKET*)(pCopyDataStruct->lpData);
if (pCopyPacket->guidSignature != CopyData_Signature)
{
// Bad GUID
return FALSE;
}
if (GetLastActivePopup() != this) // Popup windows!
{
// TODO: Tell user?
return FALSE;
}
theApp.SetFileToOpenFromFileExplorer(pCopyPacket->szFile);
OpenFileFromFileExplorer();
return TRUE;
}
return FALSE;
}
It works fine. I just wanted to know if it would be acceptable to change my structure like this:
typedef struct tagCOPY_PACKET
{
LPCTSTR lpszFile;
GUID guidSignature;
} S_COPY_PACKET;
And then use:
S_COPY_PACKET sCopyDataPacket;
sCopyDataPacket.lpszFile = strFile.GetBufferSetLength(_MAX_PATH);
sCopyDataPacket.guidSignature = CopyData_Signature;
COPYDATASTRUCT cds;
cds.dwData = COPYDATA_TYPE_MSA;
cds.cbData = sizeof(sCopyDataPacket);
cds.lpData = &sCopyDataPacket;
...
And, once the message has been posted and processed:
strFile.ReleaseBuffer();
Is it safe to use the LPCTSTR
approach with WM_COPYDATA
and if so, why?
回答1:
The documentation of WM_COPYDATA says:
The data being passed must not contain pointers or other references to objects not accessible to the application receiving the data.
Therefore, when CMeetingScheduleAssistantDlg
lives in a different executable, you cannot pass an LPCTSTR
value. If it is in the same executable, chances are that it works.
回答2:
No. LPCTSTR
is a pointer. So the recipient application will receive a pointer to a memory location of the sender application. It would cause the recipient application to crash due to a memory violation, had it tried to access the data.
来源:https://stackoverflow.com/questions/61725198/is-it-safe-to-use-lpctstr-in-a-structure-with-the-wm-copydata-message