|
I want to set the function pointer at runtime. But i'm stuck here. When i use global function or static class member function, everything is ok. but, when the function is ordinary class member functions. i always got compiler errors. Here is the code:
class A
{
int val;
public:
A() { val = 0; }
A(int j) { val = j; }
int aFun(int k) {val -= k; return val; }
};
typedef int (* func)(int );
class B
{
func m_addr;
public:
B(func param)
: m_addr(param)
{
}
void execute()
{
cout << m_addr(9) << endl;
}
};
I'm trying to use them like this:
A a;
B b(A::aFun);
b.execute();
after googled a lot, i found that std::mem_fun may be helpful. but i don't know how to use it. anyone can help me?
PS: i'm using Visual C++ 2010
|
|
|
|
|
I think the function needs to be a class function (i.e. static ).
One of these days I'm going to think of a really clever signature.
|
|
|
|
|
The code doesn't make a lot of sense. The is no connection between the member function to be called and a specific instance of A on which to call it. Also the typedef is incorrect for a non-static member function, make it look likes this:
typedef int (* A::func)(int );
Steve
|
|
|
|
|
A::aFun is different from func.
|
|
|
|
|
When you think about it, what you try to achieve isn't logically possible:
A member function that is not static implicitely takes a pointer to the instance as it's first (hidden) argument, so you cannot encode that as a simple pointer, as you always have to additionally pass that instance-pointer. Class B does not have a pointer to an instance of class A, so it cannot possibly call a member function, whether by pointer or any other mechanic!
When you look at your code, where do you use the object a ? Nowhere!
|
|
|
|
|
|
thank you very much. the command pattern is the perfect solution. 
|
|
|
|
|
Hi all,
I am a beginner in networking, I want to do a project to move my arm robot in the server (it is mac) with my p5 glove in the client (it has os window) using client server udp with c++.
In client site I have visual C to translate the movement of the glove.
In server site there are programs to move the robot in c language.
I want to ask, how to send the data/information from the glove to move the arm.
Thank you
daniel
|
|
|
|
|
First off... for something like this, I wouldn't use UDP, I would use TCP/IP. There's really no reason to use UDP, which sends datagrams with no built-in error checking, TCP/IP already handles the error checking/handling (i.e. it'll automatically retransmit packets that didn't arrive at their destination correctly). Usually you only want to use UDP when you have something that doesn't require reliability like voice or video (i.e. if you lose a packet here and there it won't really matter, you'll still be able to hear/see the other person).
As far as sending the data, if you're making for the server and client, it's easy, you define the data messages/structures that are being passed between both completely yourself (via what is typically referred to as an API). Usually the packets are made up of binary buffers, within that buffer, you can either have fixed length or variable length data buffers (or packets), the structure of which is completely up to you.
For example, you can specify:
0. first 4-bytes of the buffer define the message type
1. next 4-bytes define a message specification
2. next 4-bytes define the message size
3. so on...
In this scenario, when you receive a packet, first thing you'll do is cast it onto a data structure that is defined by your API. The first portion of the structure would be an int type (picked it because it's 4-bytes in a 32bit system) and it can specify the type of message that is contained in that data packet. The next portion can be a subset of that message and so on.
Search google and CodeProject for client/server examples and see how they defined their messages.
|
|
|
|
|
I have a CListCtrl with the LVS_EX_CHECKBOXES style and I want to limit the number of items that the user can select. I have written the following code but (of course) it gets itself in a loop because in changing the state of an item, it causes OnItemchangingLoadingValues() to be called again.
void CSpecimenLoadingDialog::OnItemchangingLoadingValues(NMHDR* pNMHDR, LRESULT* pResult)
{
NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;
int nCheckedItems = 0;
for(int i = 0; i < m_loadingVals.GetItemCount(); i++)
{
BOOL bState = ListView_GetCheckState(m_loadingVals.m_hWnd, i);
if(bState)
{
nCheckedItems++;
}
}
if(nCheckedItems == 2)
{
ListView_SetItemState(m_loadingVals.m_hWnd, pNMListView->iItem, FALSE, LVIS_STATEIMAGEMASK);
}
*pResult = 0;
}
What is the correct way to go about doing this? 
|
|
|
|
|
softwaremonkey wrote: because in changing the state of an item, it causes OnItemchangingLoadingValues() to be called again. But the parameters (i.e., state) passed each time are different.
Rather than use a for() loop each time an item's state changes, simply check the state passed and use a counter. Then in OnItemchangingLoadingValues() , you could have something like:
void CSpecimenLoadingDialog::OnItemchangingLoadingValues(NMHDR* pNMHDR, LRESULT* pResult)
{
if (nCheckedItems < 2)
{
if (pNMHDR's new state equals checked)
nCheckedItems++;
else
nCheckedItems--;
}
}
"One man's wage rise is another man's price increase." - Harold Wilson
"Fireproof doesn't mean the fire will never come. It means when the fire comes that you will be able to withstand it." - Michael Simmons
"Show me a community that obeys the Ten Commandments and I'll show you a less crowded prison system." - Anonymous
|
|
|
|
|
You may add a member variable to your class (or a static variable to the handler function) indicating that the handler is called recursive:
private:
m_bIgnoreChgHandling;
CSpecimenLoadingDialog::CSpecimenLoadingDialog()
{
m_bIgnoreChgHandling = false;
}
void CSpecimenLoadingDialog::OnItemchangingLoadingValues(NMHDR* pNMHDR, LRESULT* pResult)
{
if (!m_bIgnoreChgHandling)
{
NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;
int nCheckedItems = 0;
if(nCheckedItems == 2)
{
m_bIgnoreChgHandling = true;
ListView_SetItemState(m_loadingVals.m_hWnd, pNMListView->iItem, FALSE, LVIS_STATEIMAGEMASK);
m_bIgnoreChgHandling = false;
}
}
*pResult = 0;
}
|
|
|
|
|
Clever stuff - thanks 
|
|
|
|
|
Hi,
At work I only have Visual C++ 6.0 this seems like old compiler as everyone is using Visual Studio
I have to automate the importing of data from a .txt file to an EXCEL spreadsheet
I think using OLE is the answer
My question is, is this do-able with Visual C++ 6.0
Thanks
|
|
|
|
|
Excel, at least recent ones, can open a CSV file.
So presuming the txt file isn't already CSV all you would need to do is read it, parse it, then output in in CSV.
|
|
|
|
|
ForNow wrote: My question is, is this do-able with Visual C++ 6.0 See if this gives you any ideas.
"One man's wage rise is another man's price increase." - Harold Wilson
"Fireproof doesn't mean the fire will never come. It means when the fire comes that you will be able to withstand it." - Michael Simmons
"Show me a community that obeys the Ten Commandments and I'll show you a less crowded prison system." - Anonymous
|
|
|
|
|
I am using the wizard to set up this app the program will go to the DATA menu selection on the EXCEL spreadsheet and select import external data
My question when using the wizard to set up the project will the selection be ATL COM AppWizard or WIN32 console application
|
|
|
|
|
Visual C++ 6 will do the job just fine.
Steve
|
|
|
|
|
OLE api is Win32/C, and every C compiler (including msvc of VC6) can handle it.
Nuclear launch detected
|
|
|
|
|
Hello once again,I have been working on some project for a while now and I needed to hook a creation of processes,I have that code(hook/detour)
BOOL WINAPI CreateProcH::CreateProcessInternalW ( HANDLE hToken,
LPCWSTR lpApplicationName,
LPWSTR lpCommandLine,
LPSECURITY_ATTRIBUTES lpProcessAttributes,
LPSECURITY_ATTRIBUTES lpThreadAttributes,
BOOL bInheritHandles,
DWORD dwCreationFlags,
LPVOID lpEnvironment,
LPCWSTR lpCurrentDirectory,
LPSTARTUPINFOW lpStartupInfo,
LPPROCESS_INFORMATION lpProcessInformation,
PHANDLE hNewToken
)
clogf("start %x ref: %x",realCreateProcessInternalW,&realCreateProcessInternalW);
BOOL res = FALSE;
res = realCreateProcessInternalW(hToken,lpApplicationName,lpCommandLine,lpProcessAttributes,lpThreadAttributes,bInheritHandles,dwCreationFlags,lpEnvironment,lpCurrentDirectory,lpStartupInfo,lpProcessInformation,hNewToken);
if(res == FALSE)
return res;
Sleep(100);
vector<wchar_t*> ::iterator it;
for(it = pubvPaths.begin(); it < pubvPaths.end(); it++)
{
if(!CDetour::InjectDll(lpProcessInformation->hProcess,*it))
clogf("InjectDll(lpProcessInformation->hProcess,*it) FAILED!");
clogf("Strlen %d Injecting dll: %ls",lstrlenW(*it),*it);
}
clogf("hThread: %d hProcess: %d dwThreadId: %d dwProcessId: %d",lpProcessInformation->hThread,lpProcessInformation->hProcess,lpProcessInformation->dwThreadId,lpProcessInformation->dwProcessId);
return res;
};
LOG:
[Fri Nov 30 20:22:20 2012] CreateProcH::CreateProcessInternalW reported: start 7d843e8 ref: 741285ac
[Fri Nov 30 20:22:20 2012] CreateProcH::CreateProcessInternalW reported: Strlen 103 Injecting dll: C:/Users/JEAN/SplitPLayGUI-build-desktop-Qt_4_8_1_for_Desktop_-_MSVC2010__Qt_SDK__Debug/CreateProcH.dll
[Fri Nov 30 20:22:20 2012] CreateProcH::CreateProcessInternalW reported: hThread: 5360 hProcess: 5376 dwThreadId: 8376 dwProcessId: 1388
but the process fails to create or crashes not sure what is wrong,
So I just commented out
if(!CDetour::InjectDll(lpProcessInformation->hProcess,*it))
clogf("InjectDll(lpProcessInformation->hProcess,*it) FAILED!");
and everything logged the same way but the process actually created and ran, here is CDetour::InjectDll
bool CDetour::InjectDll(HANDLE hProcess ,wchar_t * pwstrDll)
{
LPVOID RemoteString, LoadLibAddy;
if(!hProcess)
return false;
LoadLibAddy = (LPVOID)GetProcAddress(GetModuleHandle(L"kernel32.dll"), "LoadLibraryW");
if(!LoadLibAddy)
{
clogf("GetProcAddress(GetModuleHandle(L\"kernel32.dll\"), \"LoadLibraryW\") FAILED WITH %d!",GetLastError());
return false;
}
RemoteString = (LPVOID)VirtualAllocEx(hProcess, NULL, (lstrlenW(pwstrDll)*2)+2, MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE);
if(!RemoteString)
{
clogf("VirtualAllocEx(hProcess, NULL, lstrlenW(pwstrDll)+2, MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE); FAILED WITH %d!",GetLastError());
return false;
}
if(WriteProcessMemory(hProcess, (LPVOID)RemoteString, pwstrDll,(lstrlenW(pwstrDll)*2)+2, NULL) == 0)
{
clogf("WriteProcessMemory(hProcess, (LPVOID)RemoteString, pwstrDll,lstrlenW(pwstrDll)+2, NULL) FAILED WITH %d!",GetLastError());
return false;
}
if(CreateRemoteThread(hProcess, NULL, NULL, (LPTHREAD_START_ROUTINE)LoadLibAddy, (LPVOID)RemoteString, NULL, NULL) == NULL)
{
clogf("CreateRemoteThread(hProcess, NULL, NULL, (LPTHREAD_START_ROUTINE)LoadLibAddy, (LPVOID)RemoteString, NULL, NULL) FAILED WITH %d!",GetLastError());
return false;
}
return true;
}
I hope someone else could figure it out ,thanks in advance 
|
|
|
|
|
Since nobody replied I made a much deeper research on my own, and found out that I can't really use the same DLL injection way that is used when the process is already loaded.
|
|
|
|
|
this simple program supposed to run the command ls
but the output is 1 and 2.can someone explain to me why ls not working ?
#include <stdio.h>
main()
{
int pid,stat;
if((pid=fork())==0)
{
execl("/bin/","ls",NULL);
printf("1");
exit(1);
}
else
{
wait(&stat);
printf("2");
}
}
|
|
|
|
|
The first argument to execl should contain the full path to the executable you want to run:
execl("/bin/ls","ls",NULL);
|
|
|
|
|
i understant that if i have parameters i shoud write
execl("/bin/date", "date", "-u", NULL);
how can i write the same thing with execv ?
|
|
|
|
|
Also execl returns a value that can help you tell why it isn't working.
Such as '2' which seems to pretty much always mean that it couldn't find the file it needed to execute.
|
|
|
|
|