Please refer this link
Creating array of Function Pointer (Different Signature)
In continuation with my last post, where we followed generalized approach to create function pointer array having same signature. we can’t follow same creating function pointer array having different signature. So our approach would be to create hollow body i.e. void* in C++ and object class in C#, add our function address to them and at the time of calling cast them to appropriate function signature and call the function.
here is the code what i have written:-
#include <vector>
using namespace std;
typedef void (*MySingleArgFunction) (int);
typedef void (*MyDoubleArgFunction) (int,int);
void Function1(int i)
{
cout<<"Hello in Function 1 Number " <<i<<endl;
}
void function2(int i)
{
cout<<"Hello in Function 2 Number " <<i<<endl;
}
void function3(int i,int j)
{
cout<<"Hello in Function 3 Number " <<i<<j<<endl;
}
//in calling function
// using MFC Class
CPtrArray myarr;
myarr.Add((void*)&Function1);
myarr.Add((void*)&function2);
myarr.Add((void*)&function3);
((MySingleArgFunction)myarr.GetAt(0))(10);
((MySingleArgFunction)myarr.GetAt(1))(20);
((MyDoubleArgFunction)myarr.GetAt(2))(30,40);
// Using STL Class
vector<void*> mutiplesigVec;
mutiplesigVec.push_back(&Function1);
mutiplesigVec.push_back(&function3);
((MySingleArgFunction)mutiplesigVec[0])(10);
((MyDoubleArgFunction)mutiplesigVec[1])(30,40);
Creating array of function pointer (same signature)!
Recently at Codeproject, somebody struck with problem of creating array of function pointer and use that his will, so I answered his question with following code, however I have taken this pre-assumption
- All function which are to be added have same signature
- Client should be agreeing to have STL include into the project.
#include <vector>
using namespace std;
typedef void (*MySingleArgFunction) (int);
void Function1(int i)
{
cout<<"Hello in Function 1 Number " <<i;
}
void function2(int i)
{
cout<<"Hello in Function 2 Number " <<i;
}
/// In Calling function, use this code to add and call at your will
vector<MySingleArgFunction> vecFuncPtr;
vector<MySingleArgFunction>::iterator it;
///Add Function into our data structure
vecFuncPtr.push_back(&Function1);
vecFuncPtr.push_back(&function2);
/// Call function one by one
it=vecFuncPtr.begin();
while(it!=vecFuncPtr.end())
{
(*it)(20);
it++;
}
For creating array of function pointer, wait for my next article!
MailSlot: From Client To Server (With Love)
In Continuation with my previous article on MailSlot, this article I will demonstrate communication between Server and the client. The pseudo algorithm would be :-
From Client Side:
- Open existing server mailslot using CreateFile api.
- If Successful, write to mailslot, using WriteFile Api.
Code (includes client creation again)
m_hClientMailSlot =
CreateFile(m_szSlotName, // here m_szSlotName ="\\\\.\\mailslot\\VisualCpp"
GENERIC_WRITE,
FILE_SHARE_READ,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
(HANDLE) NULL);
if(m_hClientMailSlot == INVALID_HANDLE_VALUE)
{
MessageBox(L"unable to create client mail Slot");
return;
}
TCHAR szData[MAX_PATH];
m_ctlEditWrite.GetWindowTextW(szData,MAX_PATH);
DWORD bytesWritten =0;
BOOL bFlag = WriteFile(m_hClientMailSlot,
szData,
_tcslen(szData) *sizeof(TCHAR),
&bytesWritten,
NULL);
CloseHandle(m_hClientMailSlot);
From Server Side
- Call GetMailslotInfo to retrieve number of message and message length.
- If messageCount is more than 0 (zero) call ReadFile Api to read message from MailSlot Queue.
Code
DWORD lpdNextMsgSize=0,lpdMessageCount=0,bytesRead=0; BOOL bFlag = GetMailslotInfo(m_hServerMailSlot, (LPDWORD)NULL,//Maximum Message Size &lpdNextMsgSize, &lpdMessageCount, (LPDWORD) NULL); if(bFlag == false) return; if(lpdNextMsgSize == MAILSLOT_NO_MESSAGE) return; TCHAR *szBuffer = new TCHAR[lpdNextMsgSize +1]; memset(szBuffer,0,(lpdNextMsgSize +1) * sizeof(TCHAR)); ReadFile(m_hServerMailSlot,szBuffer,lpdNextMsgSize,&bytesRead,NULL); szBuffer[bytesRead]= '\0'; MessageBox(szBuffer); delete [] szBuffer;
MailSlot : How to create Server and Client ?
MailSlot is one way IPC mechanism present in window, where server takes passive role in receiving message from the client. Means client can only write and server can only read, vice versa is not possible rather I can never tried
.
According to MSDN
“A mailslot is a mechanism for one-way interprocess communications (IPC). Applications can store messages in a mailslot. The owner of the mailslot can retrieve messages that are stored there. These messages are typically sent over a network to either a specified computer or to all computers in a specified domain. A domain is a group of workstations and servers that share a group name”
Only disadvantage I feel about this mechanism , that limit of maximum message size to 424 bytes and instead of using reliable TCP service, it’s rely more on datagram packets. So keep both point in your mind while designing or using MailSlot in your application.
Through Wikipedia article about MailSlot, I came to know NET SEND service, is created on MailSlots only, however couldn’t find any official or unofficial link from Microsoft on same.
So Writing application based on MailSlot you have utilize service of these APIS (Description is copied word by word from MSDN):-
- CreateMailSlot: Creates a mailslot with the specified name.
- GetMailslotInfo: Retrieves information about the specified mailslot.
- SetMailslotInfo: Sets the time-out value used by the specified mailslot for a read operation.
- ReadFile: Above three and this function is used by server mailslot to create and read message in it’s mailslot queue.
- CreateFile: this function is utilized client to open existing MailSlot.
- WriteFile: this function is utilized by client to write message for server mailslot, if CreateFile call is successful.
Now to Create Server Mail Slot
m_hServerMailSlot =
::CreateMailslot(m_szSlotName, // Name of the Mail Slot
0, // no limit for the message Size
0,
NULL // Security Attribute
);
// check is we are success full opening the mail slot
if(m_hServerMailSlot == INVALID_HANDLE_VALUE)
{
LPVOID lpMsgBuf;
FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
GetLastError(),
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
(LPTSTR) &lpMsgBuf,
0,
NULL
);
::MessageBox( NULL, (LPCTSTR)lpMsgBuf, L"Error", MB_OK | MB_ICONINFORMATION );
LocalFree( lpMsgBuf );
return;
}
/// If everything Ok , Just return! and Display message that we are successful in creating the Socket
MessageBox(L"Creation of Server MailSlot is successfull!!");
And To Create Client MailSlot, which open Server MailSlot
m_hClientMailSlot =
CreateFile(m_szSlotName,
GENERIC_WRITE,
FILE_SHARE_READ,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
(HANDLE) NULL);
if(m_hClientMailSlot == INVALID_HANDLE_VALUE)
{
MessageBox(L"unable to create client mail Slot");
return;
}
Now how to communicate between two, stay tuned for next post!
When to use DotNet 4.0 and When to use DotNet4.0 Client Profile?
read more here
No More VC++ Directory setting in VS2011
With release of VS2011 developer preview, you cannot set global default include/library location for all the projects. for work-around you now have to configure projects for there default include & library file location.
One More workaround for global includes and library is to put setting into User Environment Variable of INCLUDE & LIB and then reload the Solutions/project.
will keep posted!