How do I pass a COM method as an argument to a function? And Microsoft compiler error C3867
I would like to pass a COM method as an argument to a function, but I am getting this error (32-bit version of C / C ++ optimizer 32-bit for C ++ compiler for 80x86):
error C3867: 'IDispatch :: GetTypeInfoCount': list of missing function arguments; use '& IDispatch :: GetTypeInfoCount' to create a pointer to a member
What am I missing?
Many thanks.
#include <atlbase.h>
void update( HRESULT(*com_uint_getter)(UINT*), UINT& u )
{
UINT tmp;
if ( S_OK == com_uint_getter( &tmp ) ) {
u = tmp;
}
}
// only for compile purpose, it will not work at runtime
int main(int, char*[])
{
// I choose IDispatch::GetTypeInfoCount just for the sake of exemplification
CComPtr< IDispatch > ptr;
UINT u;
update( ptr->GetTypeInfoCount, u );
return 0;
}
source to share
As morechilli indicated that this is a problem in C ++. Here is the solution, thanks to my colleague Daniele:
#include <atlbase.h>
template < typename interface_t >
void update( interface_t* p, HRESULT (__stdcall interface_t::*com_uint_getter)(UINT*), UINT& u )
{
UINT tmp;
if ( S_OK == (p->*com_uint_getter)( &tmp ) ) {
u = tmp;
}
}
// only for compile purpose, it will not work at runtime
int main(int, char*[])
{
// I choose IDispatch::GetTypeInfoCount just for the sake of exemplification
CComPtr< IDispatch > ptr;
UINT u;
update( ptr.p, &IDispatch::GetTypeInfoCount, u );
return 0;
}
source to share
Looks like a straight C ++ problem.
Your method expects a function pointer.
You have a member function - (which is different from a function).
Usually, you need to either:
1. Change the function you want to pass to static. 2. Change the type of pointer expected by a pointer to a member function.
The syntax for working with member function pointers is not the best ...
The standard trick would be (1) and then pass the object to that pointer explicitly as an argument, allowing you to then call non-static members.
source to share
Boost.Function is also a sensible choice here (note that I have not tested what I wrote below, so this may require some modification - in particular, I'm not sure if you need to call some kind of trick () on your object CComPtr):
#include <atlbase.h>
#include <boost/function.hpp>
#include <boost/bind.hpp>
void update( boost::function<HRESULT (UINT*)> com_uint_getter, UINT& u )
{
UINT tmp;
if ( S_OK == com_uint_getter( &tmp ) ) {
u = tmp;
}
}
// only for compile purpose, it will not work at runtime
int main(int, char*[])
{
// I choose IDispatch::GetTypeInfoCount just for the sake of exemplification
CComPtr< IDispatch > ptr;
UINT u;
update( boost::bind(&IDispatch::GetTypeInfoCount, ptr), u );
return 0;
}
This is the same as everything mentioned above, but it hides some of the more messy syntax of using it.
source to share