我遇到了以下问题:
应用程序每秒调用一个带有一些参数的C ++程序来从该应用程序中提取数据。 C ++程序是一个WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)
来完成控制台窗口没有显示给用户。
这个“第一个程序”检查数据,然后将其写入由我的“第二个程序”(只是普通的int main()
C ++)托管的Mailslot。
这已经如上所述,但是当我尝试读取邮件槽的内容时,编码似乎不同,因为我的参数不可读,字符串的长度也不同。
两个程序都在其属性中使用Unicode。我尝试使用LPWSTR
(对于Unicode)和LPCSTR
(对于ANSI)以及相应的函数...W
和...A
,但我没有使用它。
下面我写了我的2个程序的“LPCSTR-Version”。
我的第一个程序如下:
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR szCmdLine, int iCmdShow)
{
// here I do: string test = szCmdLine;
// the parameters are like: "k1234.1234 4321.321 0 1"
// so there is no special character, just two double and to int
// asking for minimum length and number of spaces in it to get number of parameters
// if there is anything not ok I return "",
// if there is all ok, I return szCmdLine.
LPCSTR message = processParameter((LPCSTR)szCmdLine);
if (strcmp('', message) == 0)
return 0;
HANDLE hSlot;
hSlot = CreateFile(
L"\\\\.\\mailslot\\name\\of\\the\\slot",
GENERIC_WRITE, // DesiredAccess
FILE_SHARE_READ, // ShareMode
(LPSECURITY_ATTRIBUTES)NULL,// SecurityAttributes
OPEN_EXISTING, // CreationDisposition
FILE_ATTRIBUTE_NORMAL, // FlagsAndAttributes
(HANDLE)NULL // TemplateFile
);
if (hSlot == INVALID_HANDLE_VALUE)
return 0;
// send message
BOOL fResult;
DWORD cbWritten;
fResult = WriteFile(
hSlot,
message,
(DWORD)(lstrlenA(message) + 1)*sizeof(char),
&cbWritten,
(LPOVERLAPPED)NULL
);
// Handle Clean-up
CloseHandle(hFile);
return 0;
}
在我的第二个程序中看起来像这样:
HANDLE hMailSlot = NULL;
BOOL WINAPI createMailSlot()
{
hMailSlot = CreateMailslot(
L"\\\\.\\mailslot\\name\\of\\the\\slot",
0, // no maximum message size
MAILSLOT_WAIT_FOREVER, // no time-out for operations
(LPSECURITY_ATTRIBUTES)NULL // default security
);
if (hMailSlot == INVALID_HANDLE_VALUE)
{
printf("CreateMailslot failed with error %d\n", GetLastError());
return FALSE;
}
else
{
printf("Mailslot created successfully.\n");
}
return TRUE;
}
void processMessage(LPCSTR msg)
{
string message = msg;
// DEBUGGING
cout << "Message: " << message << endl;
cout << "length: " << message.length() << endl;
// do other things...
}
BOOL readSlot()
{
DWORD cbMessage;
DWORD cMessage;
DWORD cbRead;
BOOL fResult;
LPCSTR lpszBuffer;
CHAR achID[80];
DWORD cAllMessages;
HANDLE hEvent;
OVERLAPPED ov;
cbMessage = cMessage = cbRead = 0;
hEvent = CreateEvent(NULL, FALSE, FALSE, TEXT("ExampleSlot"));
if (NULL == hEvent)
{
return FALSE;
}
ov.Offset = 0;
ov.OffsetHigh = 0;
ov.hEvent = hEvent;
fResult = GetMailslotInfo(
hMailSlot, // mailslot handle
(LPDWORD)NULL, // no maximum message size
&cbMessage, // size of next message
&cMessage, // number of messages
(LPDWORD)NULL // no read time-out
);
if (!fResult)
{
printf("GetMailslotInfo failed with %d.\n", GetLastError());
CloseHandle(hEvent);
return FALSE;
}
if (cbMessage == MAILSLOT_NO_MESSAGE)
{
printf("Waiting for a message...\n");
CloseHandle(hEvent);
return TRUE;
}
cAllMessages = cMessage;
while (cMessage != 0) // retrieve all messages
{
// Create a message-number string.
StringCchPrintfA(
achID,
80,
"",
cAllMessages - cMessage + 1,
cAllMessages);
// Allocate memory for the message.
lpszBuffer = (LPCSTR)GlobalAlloc(
GPTR,
cbMessage
);
if (NULL == lpszBuffer)
{
CloseHandle(hEvent);
return FALSE;
}
fResult = ReadFile(
hMailSlot,
(LPVOID)lpszBuffer,
cbMessage,
&cbRead,
&ov
);
if (!fResult)
{
printf("ReadFile failed with %d.\n", GetLastError());
GlobalFree((HGLOBAL)lpszBuffer);
CloseHandle(hEvent);
return FALSE;
}
// process Message
processMessage(lpszBuffer);
// Concatenate the message and the message-number string.
StringCbCatA(
(STRSAFE_LPSTR)lpszBuffer,
cbMessage,
achID
);
GlobalFree((HGLOBAL)lpszBuffer);
fResult = GetMailslotInfo(
hMailSlot, // mailslot handle
(LPDWORD)NULL, // no maximum message size
&cbMessage, // size of next message
&cMessage, // number of messages
(LPDWORD)NULL // no read time-out
);
if (!fResult)
{
printf("GetMailslotInfo failed (%d)\n", GetLastError());
CloseHandle(hEvent);
return FALSE;
}
}
CloseHandle(hEvent);
return TRUE;
}
int main()
{
if(!createMailSlot())
return 1;
while (true)
{
// check Mailslot for messages
readSlot();
Sleep(1000);
}
return 0;
}
然后 processMessage()
给出一个与提交给我的第一个程序不同的参数字符串。它看起来很奇怪,不可读......
我的问题有解决方案吗?我的缺点在哪里?
编辑:我编辑了包括源代码在内的整个问题,以显示我的最新版本。
答案 0 :(得分:0)
最后我找到了解决问题的方法。 我再次复制了MSDN(https://msdn.microsoft.com/en-us/library/windows/desktop/aa365576%28v=vs.85%29.aspx)的示例代码,然后用Google搜索。 我找到了这个网站http://www.johndcook.com/blog/cplusplus_strings/,其中列出并解释了所有字符串表示。我更改了代码的一些段落,这是我的工作版本:
第一个程序:
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR szCmdLine, int iCmdShow)
{
// get parameters
char *parameter = szCmdLine;
// validate parameters
if (!test_parameter(parameter))
{
return 1;
}
// Convert char* to a wchar_t*
size_t origsize = strlen(parameter) + 1;
const size_t newsize = 100;
size_t convertedChars = 0;
wchar_t wcstring[newsize];
mbstowcs_s(&convertedChars, wcstring, origsize, parameter, _TRUNCATE);
// Source: https://msdn.microsoft.com/en-us/library/ms235631(VS.80).aspx
HANDLE hMailSlot;
hMailSlot = CreateFile(
L"\\\\.\\mailslot\\name\\of\\the\\MailSlot", // lpFileName
GENERIC_WRITE, // DesiredAccess
FILE_SHARE_READ, // ShareMode
(LPSECURITY_ATTRIBUTES)NULL,// SecurityAttributes
OPEN_EXISTING, // CreationDisposition
FILE_ATTRIBUTE_NORMAL, // FlagsAndAttributes
(HANDLE)NULL // TemplateFile
);
// testing mailslot
if (hMailSlot == INVALID_HANDLE_VALUE)
{
return 2;
}
BOOL fResult;
DWORD cbWritten;
// convert message to TCHAR for sending
TCHAR *message = wcstring;
// send message
fResult = WriteFile(
hMailSlot, // File
message, // Buffer
(DWORD)(lstrlen(message) + 1)*sizeof(TCHAR), // NumberOfBytesToWrite
&cbWritten, // NumberOfBytesWritten
(LPOVERLAPPED)NULL // Overlapped
);
// Handle Clean-up
CloseHandle(hMailSlot);
return 0;
}
第二个程序:
HANDLE hMailSlot = NULL;
BOOL WINAPI createMailSlot()
{
hMailSlot = CreateMailslot(
L"\\\\.\\mailslot\\name\\of\\the\\MailSlot", // Slot Name
0, // no maximum message size
MAILSLOT_WAIT_FOREVER, // no time-out for operations
(LPSECURITY_ATTRIBUTES)NULL // default security
);
if (hMailSlot == INVALID_HANDLE_VALUE)
{
printf("CreateMailslot failed with error %d\n", GetLastError());
return FALSE;
}
else
{
printf("Mailslot created successfully.\n");
}
return TRUE;
}
void processMessage(LPTSTR msg)
{
// convert LPTSTR to string
wchar_t *message_w = msg;
size_t max = 100;
char *message_c = new char[wcslen(message_w)];
size_t message_c_size = 100;
size_t *NumOfCharConverted = 0;
wcstombs_s(NumOfCharConverted, message_c, message_c_size, message_w, max);
string message(message_c);
// processs message as string...
}
BOOL readSlot()
{
DWORD cbMessage, cMessage, cbRead;
BOOL fResult;
LPTSTR lpszBuffer;
TCHAR achID[80];
DWORD cAllMessages;
HANDLE hEvent;
OVERLAPPED ov;
cbMessage = cMessage = cbRead = 0;
hEvent = CreateEvent(NULL, FALSE, FALSE, TEXT("ExampleSlot"));
if (NULL == hEvent)
return FALSE;
ov.Offset = 0;
ov.OffsetHigh = 0;
ov.hEvent = hEvent;
fResult = GetMailslotInfo(
hMailSlot, // mailslot handle
(LPDWORD)NULL, // no maximum message size
&cbMessage, // size of next message
&cMessage, // number of messages
(LPDWORD)NULL); // no read time-out
if (!fResult)
{
printf("GetMailslotInfo failed with %d.\n", GetLastError());
return FALSE;
}
if (cbMessage == MAILSLOT_NO_MESSAGE)
{
printf("Waiting for a message...\n");
return TRUE;
}
cAllMessages = cMessage;
while (cMessage != 0) // retrieve all messages
{
// Create a message-number string.
StringCchPrintf((LPTSTR)achID,
80,
TEXT(""), //TEXT("\nMessage #%d of %d\n"),
cAllMessages - cMessage + 1,
cAllMessages);
// Allocate memory for the message.
lpszBuffer = (LPTSTR)GlobalAlloc(GPTR,
lstrlen((LPTSTR)achID)*sizeof(TCHAR) + cbMessage);
if (NULL == lpszBuffer)
return FALSE;
lpszBuffer[0] = '\0';
fResult = ReadFile(
hMailSlot,
lpszBuffer,
cbMessage,
&cbRead,
&ov);
if (!fResult)
{
printf("ReadFile failed with %d.\n", GetLastError());
GlobalFree((HGLOBAL)lpszBuffer);
return FALSE;
}
processMessage(lpszBuffer);
// Concatenate the message and the message-number string.
StringCbCat(lpszBuffer,
lstrlen((LPTSTR)achID)*sizeof(TCHAR) + cbMessage,
(LPTSTR)achID);
// Display the message.
_tprintf(TEXT("Contents of the mailslot: %s\n"), lpszBuffer);
GlobalFree((HGLOBAL)lpszBuffer);
fResult = GetMailslotInfo(
hMailSlot, // mailslot handle
(LPDWORD)NULL, // no maximum message size
&cbMessage, // size of next message
&cMessage, // number of messages
(LPDWORD)NULL); // no read time-out
if (!fResult)
{
printf("GetMailslotInfo failed (%d)\n", GetLastError());
return FALSE;
}
}
CloseHandle(hEvent);
return TRUE;
}
int main()
{
if(!createMailSlot())
return 1;
while (true)
{
// check Mailslot for messages
readSlot();
Sleep(1000);
}
return 0;
}