|
Hi.
I have reposted it with pre tags.
I cannot see where I forgot to close anything. CLosing hPipe doesn't count as it would need to leave the while loop for that.
I am really struggling with fixing this problem. It seems so simple.
|
|
|
|
|
#pragma warning(disable:4995)
#pragma comment(lib, "shell32.lib")
#include <windows.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <wchar.h>
#include <strsafe.h>
#include <time.h>
#include "psapi.h"
#define FNAME_LEN 1000
#define PNAME_LEN 1000
#define SEND_LEN 1024
#define RECV_LEN 64
typedef struct _PIPEINST
{
OVERLAPPED Overlapped;
HANDLE hPipe;
TCHAR tzSend[SEND_LEN];
DWORD dwSendLength;
TCHAR tzRecv[RECV_LEN];
DWORD dwRecvLength;
} PIPEINST, *PPIPEINST;
typedef struct _THREAD_CONTEXT
{
HANDLE hPort;
HANDLE hCompletion;
DWORD uTemporary;
} THREAD_CONTEXT, *PTHREAD_CONTEXT;
HANDLE NewPipe(LPWSTR PipeName, LPOVERLAPPED lpOverlapped)
{
HANDLE hPipe;
hPipe=CreateNamedPipe(PipeName, PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED, PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT, PIPE_UNLIMITED_INSTANCES, PNAME_LEN*sizeof(TCHAR), PNAME_LEN*sizeof(TCHAR), 1, NULL);
if(hPipe == INVALID_HANDLE_VALUE)
{
printf("CreateNamedPipe failed.\n");
return NULL;
}
if((ConnectNamedPipe(hPipe, lpOverlapped)))
{
printf("ConnectNamedPipe failed.\n");
return NULL;
}
return hPipe;
}
VOID WINAPI CompletedWrite(DWORD dwErr, DWORD dwWritten, LPOVERLAPPED lpOverLap)
{
printf("Written %d.\n", dwWritten);
}
BOOLEAN sendd(HANDLE hPipe, PPIPEINST pPipeInst, DWORD numb, PWCHAR str)
{
PWCHAR buffer;
buffer = (PWCHAR) malloc (SEND_LEN);
swprintf(buffer, L"%d\t%ws\0\0", numb, str);
printf("Sending.. %ws\n", buffer);
StringCchCopy(pPipeInst->tzSend, wcslen(buffer)+2, buffer);
pPipeInst->dwSendLength = (wcslen(pPipeInst->tzSend) * 2);
if(WriteFileEx(hPipe, pPipeInst->tzSend, pPipeInst->dwSendLength + 2, (LPOVERLAPPED) pPipeInst, (LPOVERLAPPED_COMPLETION_ROUTINE) CompletedWrite))
{
free(buffer);
return TRUE;
}
else
{
printf("WriteFileEx failed '%d'.\n", GetLastError());
free(buffer);
return FALSE;
}
}
VOID WINAPI CompletedRead(DWORD dwErr, DWORD dwRead, LPOVERLAPPED lpOverLap)
{
printf("Read %d bytes.\n", dwRead);
}
DWORD recvv(HANDLE hPipe, PPIPEINST pPipeInst)
{
DWORD BytesRead = 0;
pPipeInst->dwRecvLength = 0;
if(ReadFileEx(hPipe, pPipeInst->tzRecv, RECV_LEN, (LPOVERLAPPED) pPipeInst, (LPOVERLAPPED_COMPLETION_ROUTINE) CompletedRead))
{
return TRUE;
}
else
{
printf("ReadFileEx failed.\n");
return FALSE;
}
}
DWORD Thread(PTHREAD_CONTEXT pThreadContext)
{
OVERLAPPED hEventOverlapped;
PWCHAR PipeName;
HANDLE hPipe;
HANDLE hEvent;
PPIPEINST pPipeInst;
BOOLEAN IsConnected;
if((hEvent=CreateEvent(NULL, TRUE, TRUE, NULL)) == NULL)
{
printf("CreateEvent failed.\n");
goto end_thread;
}
else
{
hEventOverlapped.hEvent = hEvent;
}
if((PipeName=(PWCHAR) malloc(PNAME_LEN+2)) == NULL)
{
printf("malloc(PipeName) failed.\n");
goto end_thread;
}
swprintf(PipeName, L"\\\\.\\pipe\\PipeName%d\0", pThreadContext->uTemporary);
printf("PipeName %ws.\n", PipeName);
pThreadContext->uTemporary = 1;
IsConnected = FALSE;
if((pPipeInst = (PPIPEINST) GlobalAlloc(GPTR, sizeof(PIPEINST)+2)) !=NULL)
if((hPipe = NewPipe (PipeName, &hEventOverlapped)) !=NULL)
while(TRUE)
{
if(!IsConnected)
{
WaitForSingleObjectEx(hEvent, INFINITE, TRUE);
printf("Client has connected.\n");
IsConnected = TRUE;
}
ConnectNamedPipe(hPipe, &hEventOverlapped);
if(GetLastError() != ERROR_PIPE_CONNECTED || GetLastError() == ERROR_PIPE_LISTENING)
{
printf("Client has disconnected.\n");
IsConnected = FALSE;
DisconnectNamedPipe(hPipe);
CloseHandle(hPipe);
if((hPipe = NewPipe (PipeName, &hEventOverlapped)) == NULL)
{
printf("Unable to recreate new pipe.\n");
break;
}
}
else
{
if((sendd(hPipe, pPipeInst, 1, L"string")) == FALSE)
{
printf("SendToGUI failed '%d'\n", GetLastError());
}
else
{
WaitForSingleObjectEx(hEvent, INFINITE, TRUE);
recvv(hPipe, pPipeInst);
WaitForSingleObjectEx(hEvent, INFINITE, TRUE);
printf("Retrieved %c\n", pPipeInst->tzRecv[0]);
}
}
}
end_thread:
printf("%ws pipe exiting..\n", PipeName);
if(PipeName == NULL); else free(PipeName);
if(hPipe == NULL); else CloseHandle(hPipe);
if(pPipeInst == NULL); else free(pPipeInst);
return 1;
}
void __cdecl main()
{
HANDLE hThread[1];
THREAD_CONTEXT ThreadContext;
DWORD dwThreadId;
DWORD dwi;
for (dwi=0; dwi<1; dwi++)
{
ThreadContext.uTemporary = dwi;
hThread[dwi] = CreateThread(NULL, 0, Thread, &ThreadContext, 0, &dwThreadId);
if(hThread[dwi] == NULL)
{
printf("CreateThread failed.\n");
return;
}
while(ThreadContext.uTemporary == dwi);
}
WaitForMultipleObjectsEx(dwi, hThread, TRUE, INFINITE, FALSE);
printf("Exit success.\n");
return;
}
The Client code.
#pragma warning(disable:4995)
#include <windows.h>
#include <stdlib.h>
#include <stdio.h>
#include <winioctl.h>
#include <string.h>
#include <crtdbg.h>
#include <assert.h>
#include <fltuser.h>
#include <wchar.h>
#include <strsafe.h>
#include <conio.h>
#define RECV_LEN 1000
#define SEND_LEN 1000
#define PNAME_LEN 1000
int OpenPipe(DWORD PipeNumber, PCHAR PipeName);
int ReadPipe(DWORD PipeNumber, PCHAR PipeRead, DWORD ReadLength);
int WritePipe(DWORD PipeNumber, PCHAR PipeWrite, DWORD WriteLength);
int ClosePipe(DWORD PipeNumber);
typedef struct _PIPEINST
{
OVERLAPPED Overlapped;
HANDLE hPipe;
TCHAR tzSend[SEND_LEN];
DWORD dwSendLength;
TCHAR tzRecv[RECV_LEN];
DWORD dwRecvLength;
DWORD dwState;
BOOL fPendingIO;
} PIPEINST, *PPIPEINST;
PPIPEINST pPipeInst[1];
HANDLE hEvents[1];
int WriteToLog(char* uString)
{
FILE* pFile;
if((pFile = fopen("logfile.log", "a+")) == NULL) return -1;
printf("%s\n", uString);
fclose(pFile);
return 0;
}
int __stdcall OpenPipe(DWORD PipeNumber, PCHAR PipeName)
{
DWORD dwMode;
BOOL fSuccess = FALSE;
WCHAR wBuffer[PNAME_LEN];
UCHAR ErrorMessage[1024];
pPipeInst[PipeNumber] = (PPIPEINST) malloc (sizeof(PIPEINST));
MultiByteToWideChar(CP_ACP, 0, PipeName, -1, wBuffer, strlen(PipeName));
wBuffer[strlen(PipeName)] = '\0';
hEvents[PipeNumber] = CreateEvent(NULL, TRUE, TRUE, NULL);
if(hEvents[PipeNumber] == NULL)
{
printf("CreateEvent failed.\n");
return 1;
}
pPipeInst[PipeNumber]->Overlapped.hEvent = hEvents[PipeNumber];
while (1)
{
pPipeInst[PipeNumber]->hPipe = CreateFile(wBuffer, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
if (pPipeInst[PipeNumber]->hPipe != INVALID_HANDLE_VALUE) break;
if (GetLastError() != ERROR_PIPE_BUSY) return 1;
if (!WaitNamedPipe(wBuffer, 20000)) return 1;
}
dwMode = PIPE_TYPE_BYTE;
fSuccess = SetNamedPipeHandleState(pPipeInst[PipeNumber]->hPipe, &dwMode, NULL, NULL);
if (!fSuccess) return 1;
return 0;
}
int __stdcall ReadPipe(DWORD PipeNumber, PCHAR pPipeRead, DWORD ReadLength)
{
PWCHAR PipeRead;
BOOL fSuccess = FALSE;
PipeRead = (PWCHAR) malloc (RECV_LEN);
if(PipeRead == NULL)
{
printf("malloc(PipeRead) failed.\n");
return 0;
}
ReadFile(pPipeInst[PipeNumber]->hPipe, PipeRead, RECV_LEN, NULL, &pPipeInst[PipeNumber]->Overlapped);
fSuccess = GetOverlappedResult(pPipeInst[PipeNumber]->hPipe, &pPipeInst[PipeNumber]->Overlapped, &ReadLength, FALSE);
if(fSuccess)
{
sprintf(pPipeRead, "%ws\0", PipeRead);
free(PipeRead);
return ReadLength;
}
free(PipeRead);
return 0;
}
int __stdcall WritePipe(DWORD PipeNumber, PCHAR PipeWrite, DWORD WriteLength)
{
BOOL fSuccess = FALSE;
PWCHAR wBuffer;
DWORD cbWritten;
wBuffer = (PWCHAR) malloc (SEND_LEN);
if(wBuffer == NULL)
{
printf("malloc(wBuffer) failed.\n");
return 1;
}
MultiByteToWideChar(CP_ACP, 0, PipeWrite, -1, wBuffer, strlen(PipeWrite));
wBuffer[strlen(PipeWrite)] = '\0';
fSuccess = WriteFile(pPipeInst[PipeNumber]->hPipe, wBuffer, wcslen(wBuffer) * 2, &cbWritten, NULL);
if (!fSuccess)
{
free(wBuffer);
return 1;
}
else
{
free(wBuffer);
return 0;
}
}
int __stdcall ClosePipe(DWORD PipeNumber)
{
CloseHandle(pPipeInst[PipeNumber]->hPipe);
return 0;
}
void __cdecl main()
{
PCHAR Pipe;
DWORD n = 0;
DWORD ReadLength = 0;
Pipe = (PCHAR) malloc (1024);
if(OpenPipe(0, "\\\\.\\Pipe\\PipeName0") != 0) return;
printf ("Connected.\n");
while (TRUE)
{
if((ReadLength = ReadPipe(n, Pipe, 0)) > 0)
{
printf("Read (%i bytes):\n %s\n", ReadLength, Pipe);
printf("Sending..\n");
printf("Responce: %i (1 is failure.)\n", WritePipe(n, "a", 1));
}
}
return;
}
|
|
|
|
|
A quick glance didn't reveal any dangling resource.
Do you always write code without proper indentation?
|
|
|
|
|
No I don't and I've had a look at the code too and no I can't see a problem with it. It compiles fine, the connect and disconnect code is ok. It is only when I un-rem the receive code that things majorly play up and both programs freeze. I'm stuck, really I am.
Server Code.
#pragma warning(disable:4995)
#pragma comment(lib, "shell32.lib")
#include <windows.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <wchar.h>
#include <strsafe.h>
#include <time.h>
#include "psapi.h"
#define FNAME_LEN 1000
#define PNAME_LEN 1000
#define SEND_LEN 1024
#define RECV_LEN 64
typedef struct _PIPEINST
{
OVERLAPPED Overlapped;
HANDLE hPipe;
TCHAR tzSend[SEND_LEN];
DWORD dwSendLength;
TCHAR tzRecv[RECV_LEN];
DWORD dwRecvLength;
} PIPEINST, *PPIPEINST;
typedef struct _THREAD_CONTEXT
{
HANDLE hPort;
HANDLE hCompletion;
DWORD uTemporary;
} THREAD_CONTEXT, *PTHREAD_CONTEXT;
HANDLE NewPipe(LPWSTR PipeName, LPOVERLAPPED lpOverlapped)
{
HANDLE hPipe;
hPipe=CreateNamedPipe(PipeName, PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED, PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT, PIPE_UNLIMITED_INSTANCES, PNAME_LEN*sizeof(TCHAR), PNAME_LEN*sizeof(TCHAR), 1, NULL);
if(hPipe == INVALID_HANDLE_VALUE)
{
printf("CreateNamedPipe failed.\n");
return NULL;
}
if((ConnectNamedPipe(hPipe, lpOverlapped)))
{
printf("ConnectNamedPipe failed.\n");
return NULL;
}
return hPipe;
}
VOID WINAPI CompletedWrite(DWORD dwErr, DWORD dwWritten, LPOVERLAPPED lpOverLap)
{
printf("Written %d.\n", dwWritten);
}
BOOLEAN SendToGUI(HANDLE hPipe, PPIPEINST pPipeInst, DWORD numb, PWCHAR str)
{
PWCHAR buffer;
buffer = (PWCHAR) malloc (SEND_LEN);
swprintf(buffer, L"%d\t%ws\0\0", numb, str);
printf("Sending.. %ws\n", buffer);
StringCchCopy(pPipeInst->tzSend, wcslen(buffer)+2, buffer);
pPipeInst->dwSendLength = (wcslen(pPipeInst->tzSend) * 2);
if(WriteFileEx(hPipe, pPipeInst->tzSend, pPipeInst->dwSendLength + 2, (LPOVERLAPPED) pPipeInst, (LPOVERLAPPED_COMPLETION_ROUTINE) CompletedWrite))
{
free(buffer);
return TRUE;
}
else
{
printf("WriteFileEx failed '%d'.\n", GetLastError());
free(buffer);
return FALSE;
}
}
VOID WINAPI CompletedRead(DWORD dwErr, DWORD dwRead, LPOVERLAPPED lpOverLap)
{
printf("Read %d bytes.\n", dwRead);
}
DWORD ReceiveFromGUI(HANDLE hPipe, PPIPEINST pPipeInst)
{
DWORD BytesRead = 0;
pPipeInst->dwRecvLength = 0;
if(ReadFileEx(hPipe, pPipeInst->tzRecv, RECV_LEN, (LPOVERLAPPED) pPipeInst, (LPOVERLAPPED_COMPLETION_ROUTINE) CompletedRead))
{
return TRUE;
}
else
{
printf("ReadFileEx failed.\n");
return FALSE;
}
}
DWORD Thread(PTHREAD_CONTEXT pThreadContext)
{
OVERLAPPED hEventOverlapped;
PWCHAR PipeName;
HANDLE hPipe;
HANDLE hEvent;
PPIPEINST pPipeInst;
BOOLEAN IsConnected;
if((hEvent=CreateEvent(NULL, TRUE, TRUE, NULL)) == NULL)
{
printf("CreateEvent failed.\n");
goto end_thread;
}
else
{
hEventOverlapped.hEvent = hEvent;
}
if((PipeName=(PWCHAR) malloc(PNAME_LEN+2)) == NULL)
{
printf("malloc(PipeName) failed.\n");
goto end_thread;
}
swprintf(PipeName, L"\\\\.\\pipe\\PipeName%d\0", pThreadContext->uTemporary);
printf("PipeName %ws.\n", PipeName);
pThreadContext->uTemporary = 1;
IsConnected = FALSE;
if((pPipeInst = (PPIPEINST) GlobalAlloc(GPTR, sizeof(PIPEINST)+2)) !=NULL)
if((hPipe = NewPipe (PipeName, &hEventOverlapped)) !=NULL)
while(TRUE)
{
if(!IsConnected)
{
WaitForSingleObjectEx(hEvent, INFINITE, TRUE);
printf("Client has connected.\n");
IsConnected = TRUE;
}
ConnectNamedPipe(hPipe, &hEventOverlapped);
if(GetLastError() != ERROR_PIPE_CONNECTED || GetLastError() == ERROR_PIPE_LISTENING)
{
printf("Client has disconnected.\n");
IsConnected = FALSE;
DisconnectNamedPipe(hPipe);
CloseHandle(hPipe);
if((hPipe = NewPipe (PipeName, &hEventOverlapped)) == NULL)
{
printf("Unable to recreate new pipe.\n");
break;
}
}
else
{
if((SendToGUI(hPipe, pPipeInst, 1, L"string")) == FALSE)
{
printf("SendToGUI failed '%d'\n", GetLastError());
}
else
{
WaitForSingleObjectEx(hEvent, INFINITE, TRUE);
ReceiveFromGUI(hPipe, pPipeInst);
WaitForSingleObjectEx(hEvent, INFINITE, TRUE);
printf("Retrieved %c\n", pPipeInst->tzRecv[0]);
}
}
}
end_thread:
printf("%ws pipe exiting..\n", PipeName);
if(PipeName == NULL); else free(PipeName);
if(hPipe == NULL); else CloseHandle(hPipe);
if(pPipeInst == NULL); else free(pPipeInst);
return 1;
}
void __cdecl main()
{
HANDLE hThread[1];
THREAD_CONTEXT ThreadContext;
DWORD dwThreadId;
DWORD dwi;
for (dwi=0; dwi<1; dwi++)
{
ThreadContext.uTemporary = dwi;
hThread[dwi] = CreateThread(NULL, 0, Thread, &ThreadContext, 0, &dwThreadId);
if(hThread[dwi] == NULL)
{
printf("CreateThread failed.\n");
return;
}
while(ThreadContext.uTemporary == dwi);
}
WaitForMultipleObjectsEx(dwi, hThread, TRUE, INFINITE, FALSE);
printf("Exit success.\n");
return;
}
Client Code
#pragma warning(disable:4995)
#include <windows.h>
#include <stdlib.h>
#include <stdio.h>
#include <winioctl.h>
#include <string.h>
#include <crtdbg.h>
#include <assert.h>
#include <fltuser.h>
#include <wchar.h>
#include <strsafe.h>
#include <conio.h>
#define RECV_LEN 1000
#define SEND_LEN 1000
#define PNAME_LEN 1000
int OpenPipe(DWORD PipeNumber, PCHAR PipeName);
int ReadPipe(DWORD PipeNumber, PCHAR PipeRead, DWORD ReadLength);
int WritePipe(DWORD PipeNumber, PCHAR PipeWrite, DWORD WriteLength);
int ClosePipe(DWORD PipeNumber);
typedef struct _PIPEINST
{
OVERLAPPED Overlapped;
HANDLE hPipe;
TCHAR tzSend[SEND_LEN];
DWORD dwSendLength;
TCHAR tzRecv[RECV_LEN];
DWORD dwRecvLength;
DWORD dwState;
BOOL fPendingIO;
} PIPEINST, *PPIPEINST;
PPIPEINST pPipeInst[1];
HANDLE hEvents[1];
int WriteToLog(char* uString)
{
FILE* pFile;
if((pFile = fopen("logfile.log", "a+")) == NULL) return -1;
printf("%s\n", uString);
fclose(pFile);
return 0;
}
int __stdcall OpenPipe(DWORD PipeNumber, PCHAR PipeName)
{
DWORD dwMode;
BOOL fSuccess = FALSE;
WCHAR wBuffer[PNAME_LEN];
UCHAR ErrorMessage[1024];
pPipeInst[PipeNumber] = (PPIPEINST) malloc (sizeof(PIPEINST));
MultiByteToWideChar(CP_ACP, 0, PipeName, -1, wBuffer, strlen(PipeName));
wBuffer[strlen(PipeName)] = '\0';
hEvents[PipeNumber] = CreateEvent(NULL, TRUE, TRUE, NULL);
if(hEvents[PipeNumber] == NULL)
{
printf("CreateEvent failed.\n");
return 1;
}
pPipeInst[PipeNumber]->Overlapped.hEvent = hEvents[PipeNumber];
while (1)
{
pPipeInst[PipeNumber]->hPipe = CreateFile(wBuffer, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
if (pPipeInst[PipeNumber]->hPipe != INVALID_HANDLE_VALUE) break;
if (GetLastError() != ERROR_PIPE_BUSY) return 1;
if (!WaitNamedPipe(wBuffer, 20000)) return 1;
}
dwMode = PIPE_TYPE_BYTE;
fSuccess = SetNamedPipeHandleState(pPipeInst[PipeNumber]->hPipe, &dwMode, NULL, NULL);
if (!fSuccess) return 1;
return 0;
}
int __stdcall ReadPipe(DWORD PipeNumber, PCHAR pPipeRead, DWORD ReadLength)
{
PWCHAR PipeRead;
BOOL fSuccess = FALSE;
PipeRead = (PWCHAR) malloc (RECV_LEN);
if(PipeRead == NULL)
{
printf("malloc(PipeRead) failed.\n");
return 0;
}
ReadFile(pPipeInst[PipeNumber]->hPipe, PipeRead, RECV_LEN, NULL, &pPipeInst[PipeNumber]->Overlapped);
fSuccess = GetOverlappedResult(pPipeInst[PipeNumber]->hPipe, &pPipeInst[PipeNumber]->Overlapped, &ReadLength, FALSE);
if(fSuccess)
{
sprintf(pPipeRead, "%ws\0", PipeRead);
free(PipeRead);
return ReadLength;
}
free(PipeRead);
return 0;
}
int __stdcall WritePipe(DWORD PipeNumber, PCHAR PipeWrite, DWORD WriteLength)
{
BOOL fSuccess = FALSE;
PWCHAR wBuffer;
DWORD cbWritten;
wBuffer = (PWCHAR) malloc (SEND_LEN);
if(wBuffer == NULL)
{
printf("malloc(wBuffer) failed.\n");
return 1;
}
MultiByteToWideChar(CP_ACP, 0, PipeWrite, -1, wBuffer, strlen(PipeWrite));
wBuffer[strlen(PipeWrite)] = '\0';
fSuccess = WriteFile(pPipeInst[PipeNumber]->hPipe, wBuffer, wcslen(wBuffer) * 2, &cbWritten, NULL);
if (!fSuccess)
{
free(wBuffer);
return 1;
}
else
{
free(wBuffer);
return 0;
}
}
int __stdcall ClosePipe(DWORD PipeNumber)
{
CloseHandle(pPipeInst[PipeNumber]->hPipe);
return 0;
}
void __cdecl main()
{
PCHAR Pipe;
DWORD n = 0;
DWORD ReadLength = 0;
Pipe = (PCHAR) malloc (1024);
if(OpenPipe(0, "\\\\.\\Pipe\\PipeName0") != 0) return;
printf ("Connected.\n");
while (TRUE)
{
if((ReadLength = ReadPipe(n, Pipe, 0)) > 0)
{
printf("Read (%i bytes):\n %s\n", ReadLength, Pipe);
printf("Sending..\n");
printf("Responce: %i (1 is failure.)\n", WritePipe(n, "a", 1));
}
}
return;
}
|
|
|
|
|
Three posts of the same information! Why not just edit the original?
|
|
|
|
|
I didn't know I could.
Done.
I hope someone can help.
|
|
|
|
|
1. Initialize all variables!
2. Use calloc if you aren't going to set the contents right away, or they will be set by another function.
e.g. Client - OpenPipe()
pPipeInst[PipeNumber] = (PPIPEINST) calloc (1, sizeof(PIPEINST));
Without this your first call to ReadFile will have random garbage in the overlapped structure which may cause it to fail or corrupt or hang.
3. you aren't using overlapped as intended. Your client main() spins on a non-blocking ReadPipe(). I expect that ReadFile() posts an overlapped read but doesn't finish, main calls again, pending still not done but tries to post another overlapped read using the same overlapped structure. This likely hoses the state of the first read and who knows what else. Easy fix: use GetOverlappedResult(..., TRUE) i.e. make it wait for the read to finish. Proper fix: Redo design to use overlapped properly.
...cmk
The idea that I can be presented with a problem, set out to logically solve it with the tools at hand, and wind up with a program that could not be legally used because someone else followed the same logical steps some years ago and filed for a patent on it is horrifying.
- John Carmack
|
|
|
|
|
Hello folks!
This is probably a very simple question i just don't know how to/where to look for the answer...so, i better give you an example:
typedef int(* FUNC_ONE)(int);
typedef int(* FUNC_TWO)(int, int);
int Func(int x)
{
return x;
}
int Func(int x, int y)
{
return x + y;
}
FUNC_ONE pFuncOne = Func;
FUNC_TWO pFuncTwo = Func;
My question is: how do i tell the compiler to use the one parameter version of Func when assigning the value to pFuncOne and use the two param version of Func when assigning the value to pFuncTwo . As it is written in the example it passes the first pointer assignment but gives error on the second one as it is trying to assign the first, one parameter version of Func to the FUNC_TWO type pointer too. I wonder, if i explicitly specify the types, like this:
FUNC_ONE pFuncOne = (FUNC_ONE)Func;
FUNC_TWO pFuncTwo = (FUNC_TWO)Func; will it use the correct function address or will it in both cases use the one parameter version just convert it to FUNC_TWO in the second assignment.
Thanks for any help in advance. Oh, and happy new year to you all!
p.s: i would like to solve this without having to rename the functions.
> The problem with computers is that they do what you tell them to do and not what you want them to do. <
> Sometimes you just have to hate coding to do it well. <
|
|
|
|
|
What happened when you compiled and ran it?
On my system it worked correctly, as the compiler figured out the correct call from the typedef and function signature.
|
|
|
|
|
You mean with the explicit conversion, right? Currently i am unable to test it in runtime because it is part of a bigger project and i still need to do a lot of work before it becomes "runnable".
An alternative solution for me could be to create another method (or two methods) with different names and same parameters and then from these call the right Func , but this isn't that elegant (but still less problematic than renaming the functions everywhere)...
I mean something like this:
int Func1(int x) { return Func(x); }
int Func2(int x, int y) { return Func(x, y); }
...
FUNC_ONE pFuncOne = Func1;
FUNC_TWO pFuncTwo = Func2;
> The problem with computers is that they do what you tell them to do and not what you want them to do. <
> Sometimes you just have to hate coding to do it well. <
|
|
|
|
|
Code-o-mat wrote: Currently i am unable to test it in runtime because it is part of a bigger project and i still need to do a lot of work before it becomes "runnable".
I always have a couple of simple "test apps" on my machines (one C++ and one C#) which I can slot things into to try out if I'm unsure of how to do them, or of usages, or to try simple versions of algorithms, or just to test ideas. Easy to set up, and very handy.
There are three kinds of people in the world - those who can count and those who can't...
|
|
|
|
|
I just realized i have made a mistake, in our project the two "same-name" methods have different return types while in the typedefs i used the same for both and this caused the conversion problem, not that it couldn't decide which version of the function to use. Fixing the typedefs seems to have solved it. My bad. Thanks for the help anyways, i guess i should pay more attenction to details...
> The problem with computers is that they do what you tell them to do and not what you want them to do. <
> Sometimes you just have to hate coding to do it well. <
|
|
|
|
|
Code-o-mat wrote: Currently i am unable to test it
Just paste it into a simple console app and call from main() , takes but a few minutes to test.
Your alternative appears to be an equally good solution. Without knowing a lot more about your project it's difficult to offer much more advice. Either way you seem to have the answer at your fingertips.
[edit]spelling[/edit]
|
|
|
|
|
Thank you for the suggestion, i sometimes do that too, should have thought of it this time too, guess i am tired. Aside of this, see my other post[^] for the "solution"...
> The problem with computers is that they do what you tell them to do and not what you want them to do. <
> Sometimes you just have to hate coding to do it well. <
|
|
|
|
|
I think your signature(s) say it all.
I'm sure you'll get it right after a good night's sleep ... and maybe some beer.
|
|
|
|
|
In your first example, the one without the C-style cast, the type system should prevent you from performing an illegal assignment -- in other words the right thing would have to happen or a compiler error be generated. Because the compiler will not allow the following:
typedef int(* FUNC_ONE)(int);
int Func2Parm(int x, int y)
{
return x + y;
}
FUNC_ONE pFuncOne = Func2Parm;
Once you introduce the explicit cast, I am not sure what will happen. I would have guessed that the compiler would report an ambiguity error (after all it could cast either pointer that way).
|
|
|
|
|
Code-o-mat wrote: I declare two function pointer types [...]
Have you considered using C++ virtual functions[^]... just a suggestion.
|
|
|
|
|
Thanks for the suggestion but i don't see how that would apply to this situation.
> The problem with computers is that they do what you tell them to do and not what you want them to do. <
> Sometimes you just have to hate coding to do it well. <
|
|
|
|
|
Well, when I saw function pointers I thought that the design pattern you try to implement is something like a callback or interchangeable functionality. In object oriented languages, polymorphism (virtual functions or delegates) provides exactly that and under the hood they are more or less function pointers, with the advantage that the compiler takes care of most things automatically (type safety, calling context). It could be worth to have a look at these possibilities.
For using virtual functions define a interface (pure virtual base class) that you can override:
class IFunctionInterface
{
public: virtual int Func(int x) = 0;
public: virtual int Func(int x, int y) = 0;
};
class CFunction1 : public CWhatever, public IFunctionInterface
{
public:
CFunction1 ();
virtual ~CFunction1 ();
int Func(int x) { return x; }
int Func(int x, int y) { return x + y; }
};
class CFunction2 : public CWhatever, public IFunctionInterface
{
public:
CFunction2 ();
virtual ~CFunction1 ();
int Func(int x) { return x + x; }
int Func(int x, int y) { return x * y; }
};
For delegates have a look at Boost library (function/bind/signal) or Fast C++ Delegates[^] here at CodeProject.
Hope this helps.
/M
|
|
|
|
|
Hai,
I am Having A MFC DialogBox & I want to store some values to the DataBase.Can Any One Tell Me how to do this?Previously I haven't worked with Any Data Base Application.Can AnyOne Give Me Simple Examples On this.
Thanks
|
|
|
|
|
A lot of information is available here[^]. For examples you can browse the content on codeproject
You need to google first, if you have "It's urgent please" mentioned in your question.
_AnShUmAn_
|
|
|
|
|
|
Hi,
I am using CListControl in Dialog and one of the column is checkbox.How would I capture change (check/uncheck) in checkbox in any of the row.Thanks for help.
Regards
|
|
|
|
|
itkid wrote: I am using CListControl in Dialog and one of the column is checkbox.
Did you actually put a check box in each row of that coloumn or just an ICON of check/uncheck marks?
|
|
|
|
|
conditional checkbox is present in few row. I just want to capture any change in any checkbox.
|
|
|
|
|