Skip to main content
gamedev.net
🔒 Locked

ATL/COM function pointer problem

Started by timmiepoo 0 replies 800+ views
Original Post
timmiepoo
timmiepoo
hello all. allow me to preface this post by saying that i am by no means an ATL/COM expert -- not even close. i''m in a situation where i have to figure this out as i go. i have some good reference material, but i''m stuck. hopefully one of you gurus can help me out. here goes... i''m in the process of wrapping an existing C API in COM server that will be called from ASP pages. there is one interface, ITask, exposing an Execute() method, which is the primary workhorse. from inside this Execute() function, i make calls to the afore-mentioned API. one of these API functions expects a function pointer as a parameter, like so:
hr = p4SetOutputFunction (sessionHandle, //long
						processReportData) //function pointer
 
the p4SetOutputFunction() uses the function pointer param to set up a callback to handle each line of report output. for instance, if the API were used in a Windows console app, the processReportData() function would print each line of report output to stdout. now here is my problem. p4SetOutputFunction() and processReportData() are now contained in my COM Interface. a function pointer to processReportData() in C++ now also passes a hidden pointer to this (the CTask object -- my implementation of the ITask interface). but i can''t modify the arg list for p4SetOutputFunction(), because it''s part of an existing API. so i''m stuck trying to figure out how to pass the function pointer. sorry for the long-winded explanation. if it''s still clear as mud, please let me know and i''ll try to explain a little better. i''m doing the best i can at explaining with my limited knowledge. i''ll be grateful for any suggestions. thanks!
timmiepoo
timmiepoo
posting some source code to hopefully clear up my terrible explanation...

My COM object has one Interface, ITask, implemented by the CTask class. It currently exposes one method, Execute():


  
STDMETHODIMP CTask::Execute(BSTR bstrTaskName, BSTR bstrMachine, BSTR bstrCoDiv, BSTR bstrOperId,
BSTR bstrOperPassword, BSTR bstrSystemUserId, BSTR bstrSystemPassword,
BSTR bstrEnvironment, int iPort, BSTR bstrParams, BSTR *pbstrOutput)
{
}


Inside this method, i make a call to an API function. Not the Win32 API. Another API that our primary business software uses. It''s a DLL written by another company. The call looks like this:


  
p4SetOutputFunction (sessionHandle, lpFunc);


The second parameter is the problem. The API expects a function pointer to use as a callback for writing report data line-by-line. But the function I need to use is a member of CTask. So, the API is expecting this:

(*)(long,int,int,int,int,const char *)

but i''m passing it this:

(CTask::*)(long,int,int,int,int,const char *)

i''ve tried various ways of casting the pointer, including the following:


  
// global function pointer declaration, not a member of CTask

int (*lpFunc)(long,int,int,int,int,const char *);

STDMETHODIMP CTask::Execute(BSTR bstrTaskName, BSTR bstrMachine, BSTR bstrCoDiv, BSTR bstrOperId,
BSTR bstrOperPassword, BSTR bstrSystemUserId, BSTR bstrSystemPassword,
BSTR bstrEnvironment, int iPort, BSTR bstrParams, BSTR *pbstrOutput)
{
// point global function pointer to my CTask function

lpFunc = CTask::processReportOutputData;
}


i''m still getting this error:

error C2440: ''='' : cannot convert from ''int (__thiscall CTask::*)(long,int,int,int,int,const char *)'' to ''int (__cdecl *)(long,int,int,int,int,const char *)''
There is no context in which this conversion is possible

anyone know how i can make this work, without rewriting the existing API to accept a class function pointer? i''m trying to figure out (1) if it''s possible, and (2) how to do it. if it''s not possible, i can find out if i can modify and recompile the DLL. right now i''m just trying to figure out if there is an alternative, since i can''t seem to figure it out. thanks!

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.