I can't get this code to work...

typedef bool (* ProcessCallback)(DWORD ProcessId, DWORD ParentProcessId, TCHAR * Path, void * ImageBase, DWORD ImageSize);

bool EnumProcesses(ProcessCallback Callback);

// ---------

class cProcessList
    struct sProcess
        DWORD ProcessId;
        TCHAR Path[MAX_PATH];

    std::vector<sProcess> List;

    bool operator()(DWORD ProcessId, DWORD ParentProcessId, TCHAR * Path, void * ImageBase, DWORD ImageSize)
        sProcess Process;
        Process.ProcessId = ProcessId;
        _tcsncpy(Process.Path, Path, _countof(Process.Path)-1);
        Process.Path[_countof(Process.Path)-1] = _T('\0');
        return false;

cProcessList Processes;
EnumProcesses(Processes); // Fails
cannot convert parameter 1 from 'cProcessList' to 'ProcessCallback'
No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called

// ---------

bool CrapFunc(DWORD ProcessId, DWORD ParentProcessId, TCHAR * Path, void * ImageBase, DWORD ImageSize)
    return false;

EnumProcesses(&CrapFunc); // Compiles ok


Line 1: error: typedef 'ProcessCallback' is initialized (use __typeof__ instead)
compilation terminated due to -Wfatal-errors.

EnumProcesses is not the psapi one, it's a wrapper for the toolhelp api. Yeah the name is misleading I guess, I don't include psapi.h so that's not the problem.
What EnumProcesses does, is call the provided callback for each process in the system.

I wanted to grab a list of processes in a vector so I wrote that class. I could have used a normal function (like Crapfunc demonstrates) but that would require a global vector and I don't like that too much (thread safety and whatnot :>).
I remember reading that overloading the () operator can be used for stuff that take function pointers. However, it doesn't compile :|

Can I even do it like that? I was told to take a look at how std::find_if does it but it uses a template that defines the callback param as a class which seems to work if you just give it a function address, since both function and class define operator().
I was rather looking for a way that would work with ordinary C...

Thanks for your help :)

7 Years
Discussion Span
Last Post by Ancient Dragon

I think you are mixing the pointer to Function with Pointer to member Function, I am giving you a little example on How to solve your problem.

class Foo {
	bool operator()(const int a) {
		return (a==1);

// Don't pass Pointer to Function.
typedef bool (*PF)(const int);
//bool DoSomething(PF pFunction) {
bool DoSomeThing(Foo& f) {	
	return f(1);

typedef bool (Foo::*PMF)(const int a);
bool DoSomeThingElse(Foo& obj, PMF pMemFunction) {
	return (obj.*pMemFunction)(1);

int main()
	Foo f;
	bool ans = DoSomeThing(f);
	PMF pMemFunc;
	bool memFunction = DoSomeThingElse(f, &Foo::operator ());

	return 0;

In the Code above I commented the pointer to function because in your case you are using Functor or Function object which are treated as pointer to member function, so I beleive passing the object directly or passing the object and pointer to member function are the solutions to your problem. I think code explains the difference between the two.

Hope this helps!.


Thanks for your reply, but that's not what I was trying to accomplish.
Member function pointers would force the user to use a special class (Foo) instead of being able to provide their own (member or non-member) callback function.
If I did that I might as well create a class Foo that also does all the enumeration, so you can access a list of processes via, say:

// overloading Foo::operator[] goes here
Foo meh;
for(int i = 0; i < meh.count(); i++) cout << meh.processid;

That's precisely what I'm doing now.

And as I said earlier, EnumProcesses is my own function, it has nothing to do with psapi whatsoever. I just happened to call it that smile.gif As long as I don't include psapi.h this should work just fine.


Line 15 of your original post is wrong because Process is not a function pointer.

int main( int argc, char* argv[] )
  return 0;
This topic has been dead for over six months. Start a new discussion instead.
Have something to contribute to this discussion? Please be thoughtful, detailed and courteous, and be sure to adhere to our posting rules.