|
|
Nemanjas link shows why you can't call member functions like this.
If declaring the method static isn't what you need (maybe your DoIt() method needs to access
non-static members of the class, for instance), it IS possible to call a member function through
a pointer, but as with all non-static class members, an object of that class is required.
The syntax is a little crazy but it's consistent with function pointers...
int Class::DoIt(float x, char y, char z)
{
return 0;
}
...
typedef int (Class::*ClassDoItPtr)(float, char, char);
...
void PassPtr(ClassDoItPtr pt2Func)
{
Class classobject();
int result = (classobject.*pt2Func)(12, 'a', 'b');
}
Hopefully I got that right
Mark
"Posting a VB.NET question in the C++ forum will end in tears." Chris Maunder
|
|
|
|
|
Hmm... I'm looking at this example, and the typedef is quite messy, however I assume it means you're typedefing the function pointer to something called ClassDoItPtr. Then, you initialize the ClassDoItPtr - so far so good.
The problem I have with this is that you have to create a whole new object of type Class, otherwise, it would look like a very good, easy solution.
Give me some time to ponder this issue -- I've got an implementation idea.
|
|
|
|
|
Yeah, the typedef just makes an alias for the function pointer type so you can use one word
instead of an entire function prototype. That's why you could declare your PassPtr() function
either of the ways I showed.
I've been trying to think of an example where this is useful but I can't! LOL Google shows some
ideas but I can't imagine a real-world example of why I'd need to use member pointers unless
I needed to mess with polymorphism at runtime.
Regardless, it's probably useless for your needs - I just wanted to point out that it could be
done Like you mentioned, needing an entire object just to make the call through a pointer
makes the whole thing kinda overkill.
If you're interested, I googled "member function pointers" for reasons why I might want to use
them. Now my head hurts - C++ overload
Cheers!
Mark
"Posting a VB.NET question in the C++ forum will end in tears." Chris Maunder
|
|
|
|
|
What about using the existing this pointer in order to make the function call? I'm trying to implement a class that will do that, right now.
The reason why I want to do this is for a generic function caller.
All I have to do is call Process(somefunction) and it will process the function (by using one of the threads in my self-implemented ThreadPool class). I made a post earlier, with a stripped down version of it, to see if I could garner any design comments, but no one replied to that post.
MODIFIED:
Actually, I had another question about your implementation, Mark. You first create the function pointer from the existing this object. Then you create a new object of the same type as this, and you try to call the function pointer from the newly created object. Are you sure that works? Wouldn't you have to create the new object first?
|
|
|
|
|
Is PassPtr() actually Class::PassPtr()? If so, then yes, you can call through the this pointer
and eliminate the need to create a separate object.
I think this is the syntax:
void Class::PassPtr(int (Class::*pt2Func)(float, char, char))
{
int result = (this->*pt2Func)(12, 'a', 'b');
}
Cyrilix wrote: You first create the function pointer from the existing this object. Then you create a new
object of the same type as this, and you try to call the function pointer from the newly created
object. Are you sure that works? Wouldn't you have to create the new object first?
Working from your sample code, I didn't have the full implementation of "Class" so I just showed
an object (classobject) created with a default constructor: "Class classobject();"
Yes you'd want to (actually you'd need to) properly construct a Class object.
I did that because you didn't show PassPtr() as a member of Class, but if it is a member, see
above...
Mark
"Posting a VB.NET question in the C++ forum will end in tears." Chris Maunder
|
|
|
|
|
Hi,
I'm trying to figure out how I can set registry key permissions in C++ so that I can then delete them using RegDeleteKey() (and not get the Access is denied error code).
Does anyone know how to do this?
Thanks!
KR
|
|
|
|
|
I've been trying to change the registry key permissions by using the access control list, but I still have some questions:
So I'm able to get as far as getting the ACL for one of my registry keys, and iterating through the ACE's of that ACL. But my problem is, how can I tell which ACEs have which permissions set? I want to find any that have the Delete permission denied, and remove those from the list (using DeleteAce()) but I don't know how to tell which ACEs have Delete denied for any users.
int FindAceIndexToDelete(PACL pACL)<br />
{<br />
int i = 0;<br />
PVOID pTempAce;<br />
int i = 0;<br />
<br />
while (1) {<br />
if (!GetAce(pACL, i, &pTempAce))<br />
break;<br />
<br />
i++;<br />
}<br />
}
KR
|
|
|
|
|
Nevermind, I got it.
GetNamedSecurityInfo on the key, GetAce on the ACL, find the ACE with header type = ACCESS_DENIED_ACE_TYPE, DeleteAce on all of those, then SetNamedSecurityInfo to set the new stuff.
KR
|
|
|
|
|
Hi all. Im trying to make a some what secret question program but im failing over and over. Its pretty simple and i thought i could create something pretty simple. What its supposed to do is ask what the secret question is and if the answer is provided then it would inform the user. And if if not then then again, it would inform the user. Here's my code:
<br />
#include <iostream><br />
using namespace std;<br />
<br />
<br />
<br />
int main()<br />
{<br />
const int MAX_SIZE=100;<br />
char hiddenword[MAX_SIZE]="secret"; <br />
printf("Type the word: ");<br />
cin.getline(hiddenword, MAX_SIZE);<br />
if(!hiddenword){<br />
printf("That is a incorrect word...try again\n");<br />
}<br />
else{<br />
printf("Congradulations! You figured out the secret word!\n");<br />
}<br />
system("pause");<br />
return 0;<br />
}<br />
No matter how many ways i move it around and around it does'nt achieve the desired functionality. Any suggestions?? Thanx in advance!
|
|
|
|
|
You're overwriting hiddenword when you call the cin.getline() function, among other problems.
What you need to do is get the arg in a separate char array and compare that to hiddenword using strcmp or something similar.
This is how I would do it:
int main()<br />
{<br />
const int MAX_SIZE=100;<br />
char hiddenword[MAX_SIZE]; <br />
char typedword[MAX_SIZE];<br />
sprintf(hiddenword, "secret");<br />
printf("Type the word: ");<br />
cin.getline(typedword, MAX_SIZE);<br />
if(strcmp(hiddenword, typedword)){
printf("That is an incorrect word...try again\n");<br />
}<br />
else{<br />
printf("Congratulations! You figured out the secret word!\n");<br />
}<br />
system("pause");<br />
return 0;<br />
}
KR
|
|
|
|
|
As an aside, you're not using C, because you use cin. I'd recommend moving all this code to use C++, for example, using cout instead of printf, and std::string instead of char arrays.
Christian Graus - Microsoft MVP - C++
Metal Musings - Rex and my new metal blog
"I am working on a project that will convert a FORTRAN code to corresponding C++ code.I am not aware of FORTRAN syntax" ( spotted in the C++/CLI forum )
|
|
|
|
|
When I run a module using ShellExecuteEx() i get access to two Handles, a hInstance and a hProcess. How can I use either at a later stage to determine whether the module is still running, How can I use either to kill the instance of the module that ShellExecuteEx() started.
Regards
LateNightsInNewry
|
|
|
|
|
If you want to kill the process, look at this article here.
I'm not sure about how to determine whether the module is running :s sorry
Hope this helps!
--PerspX
|
|
|
|
|
LateNightsInNewry wrote: How can I use either at a later stage to determine whether the module is still running,
The hProcess member (assuming you've used the SEE_MASK_NOCLOSEPROCESS flag) of SHELLEXECUTEINFO
can be used in a synchronization wait function - it will be signaled when the process terminates.
// polling method - wait timeout is 0
if (WAIT_OBJECT_0 == ::WaitForSingleObject(ShellExecuteInfo.hProcess, 0))
{
//process has ended
}
A process should be allowed to terminate normally. If you absolutely must terminate it from
another process you can use TerminateProcess with the same handle as above. Remember you
don't know the state of the other process when you do this so data loss can occur. It's
much better to get the other process to terminate itself normally if at all possible.
Mark
"Posting a VB.NET question in the C++ forum will end in tears." Chris Maunder
|
|
|
|
|
Thanks for the help Mark, Tried it, works as advertised. I understand your remark about processes terminating itself normally. I would use the Terminate Process on this occasion as a last resort, if the overnight housekeeping task which was started, and normally completes in minutes, hangs and is still active after several hours, potentially locking users out the next morning.
Thanks again,
LateNightsInNewry
|
|
|
|
|
I am having a problem getting my project to load an icon on VS 2005, VC++.net
AfxGetApp()->LoadIcon(IDI_SIMLEY) There is nothing wrong with this function cos IDI_EXCLAIMATIN work fine. But I am not too sure about the .rc script.
afxres.rc has one line that is
AFX_IDI_STD_FRAME ICON "smiley.ico"
and resource.h
#define IDI_SIMLEY (LPCTSTR)101
Clicking on the RC shows that the icon is there fixed to AFX_IDI_STD_FRAME, instead of the icon the window icon displays (which is the default icon)
|
|
|
|
|
IDI_SIMLEY
AFX_IDI_STD_FRAME
I see different IDs there....which one is correct?
LoadIcon() isn't enough to set a window icon.
You need to call CWnd::SetIcon() with the loaded icon's HICON.
Mark
"Posting a VB.NET question in the C++ forum will end in tears." Chris Maunder
|
|
|
|
|
IDI_SIMLEY is in the include file which goes like
#define IDI_SIMLEY 101
while AFX_IDI_STD_FRAME is in the .rc file. I am using AfxGetApp()->LoadStandardIcon in the Create ( NULL, "windows",........) function which is part of CFrameWnd.
How do I use CWnd::SetIcon in this case?
|
|
|
|
|
I'm not sure how you are using LoadStandardIcon() in CFrameWnd::Create(). None of the Create()
parameters take an HICON.
Regardless, LoadStandardIcon() loads system icons. To load an icon from your app's resources
you need to load them yourself.
Here's one way to change a window's icon after it has been created:
if (MyFrameWnd.Create(NULL, "windows",........))
{
HICON hIcon = AfxGetApp()->LoadIcon(IDI_SIMLEY);
MyFrameWnd.SetIcon(hIcon, TRUE);
}
Another method is to use a custom window class instead of the default MFC window class and
specify an HICON in that window class. A window created using that windowclass will use that
icon by default.
Mark
"Posting a VB.NET question in the C++ forum will end in tears." Chris Maunder
|
|
|
|
|
I have a service that runs at idle dispatch priority because it is a continuously running background process that monitors certain resources. It starts when the machine is booted and ends when the machine is shut down.
As a result of being run at idle dispatch priority it accumulates a lot of page faults. Being a background process this performance hit is not a problem but I am concerned that the page fault number will climb to a point where it may cause problems, both perceptually and possibly to processes monitoring activity.
Is there a way of resetting page fault count periodically without going through the exercise of unloading and reloading the service just to reset the counter?
|
|
|
|
|
#ifndef GLINIT_H
#define GLINIT_H
#ifdef _EXPORT
#define GLAPI __declspec(dllexport)
#else
#define GLAPI __declspec(dllimport)
#endif
GLAPI void GLInit()
{
int i;
i++;
return;
}
#endif
Can someone tell me why this is not allowed in a header? I want to simply include this header and have the includer call GLInit().
The error I get when compiling with VC 2005 is:
error C2491: 'GLInit' : definition of dllimport function not allowed
I'd like to add that there is no practical reason for me to do this, because I can simply include the function without exporting, however, I'm playing around with exporting and can't figure out the problem.
|
|
|
|
|
try this:
#ifdef _EXPORT
#define GLAPI __declspec(dllexport)
#else
#define GLAPI __declspec(dllimport)
#endif
#ifdef _EXPORT
GLAPI void GLInit()
{
int i;
i++;
return;
}
#endif
you should move your implementation to a .cpp - File or use the macro from above.
|
|
|
|
|
Yes, but what if I want to include a global function? If I were to write the function in a .cpp, I'd have to include the .cpp. I don't think the file extension makes any difference at all, but it just feels weird including a .cpp.
|
|
|
|
|
The header file should just contain the declaration (prototype) for the function.
The actual definition of the function should be moved out of the header to a single .c/.cpp file.
That c/cpp file should only be in the dll project. The header can be used in the dll project
and app projects which use the dll.
#ifndef GLINIT_H
#define GLINIT_H
#ifdef _EXPORT
#define GLAPI __declspec(dllexport)
#else
#define GLAPI __declspec(dllimport)
#endif
GLAPI void GLInit();
#endif
void GLAPI GLInit()
{
int i; <code><-- i is uninitialized!</code> :)
i++;
return;
}
"Posting a VB.NET question in the C++ forum will end in tears." Chris Maunder
|
|
|
|