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
{
public:
    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');
        List.push_back(Process);
        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

Output:


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 :)

Recommended Answers

All 4 Replies

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 {
public:
	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!.

The parameter to EnumProcesses() is not a function pointer, but a pointer to an array of DWORDs. That link contains a simple example program to demonstrate how it works.

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;
meh.update();
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[] )
{  
EnumProcesses(CrapFunc);
  return 0;
}
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.