Click here to Skip to main content
15,884,298 members
Please Sign up or sign in to vote.
4.00/5 (1 vote)
Hello,
I tried to add a function with a function pointer as parameter to my ATL C++ project.
Unfortunately, VS2008 doesn't provide function pointer as parameter type! :-(
In my non-ATL DLL library, I declared my function as following:
C++
void SetCashierDisplayEventHandler(void (*CashierDisplayEvent)(char Text[1024]));

And I implemented the function this way:
C++
extern "C" void WINAPI SetCashierDisplayEventHandler(void (*CashierDisplayEvent)(char Text[1024]))
{
	CSharedData::CashierDisplayEventRef = CashierDisplayEvent;
}

Is it possible to do what I want to do in an ATL project?
Thank you very much in advance for your suggestions.
Regards.
Posted

1 solution

It depends on architecture of your application.
Any COM method accepts only "known" parameters in its methods which are primitive datatypes, VARIANT-based or user defined interfaces. So if you want to invoke some method in its implementation it must be defined in some other interface. And your COM-interface method should pass with pointer to another interface, not method. Try to create .idl file and compile it with /TLBOUT parameter.
Lets see an example.
C++
library IMParameterLib
{
	importlib("stdole2.tlb");

        // Test Interface
	[
		odl,
		uuid(33377793-AABB-CCCC-DDDD-F0000000000F),
		version(1.0),
		helpstring("Test method interface"),
		dual,
		nonextensible,
		oleautomation
	]
    interface IMethodTest : IDispatch{
        [id(0x00000009), helpstring("parameter function")]
        HRESULT ExchangeData([in] BSTR data);

        [id(0x00000010), helpstring("test function")]
        HRESULT SetTaskData([in] LONG type,
                            [in] void (*ExchangeData)(BSTR Text)
                            );
    };
}

After compilation in .tlb file we'll see
C++
interface IMethodTest : IDispatch {
        [id(0x00000009), helpstring("parameter function")]
        HRESULT ExchangeData([in] BSTR data);
        [id(0x60020001)]
        void __MIDL_0011(BSTR Text);
        [id(0x00000010), helpstring("test function")]
        HRESULT SetTaskData(
                        [in] long type, 
                        [in] IMethodTest* ExchangeData);
    };

So what we got after compilation? The pointer to IMethodTest interface! Therefore compiller sets only "known" data type for it, not an anonymous function (even if it defined within interface), which appears as void __MIDL_0011(BSTR Text);

but if we'll do dome changes like
C++
    [
		uuid(99933366-FFFF-EEEE-DDDD-EEEEEEEEEEEE),
		version(1.0),
	]
    interface IMethodToInvoke : IDispatch{
        [id(0x00000009), helpstring("parameter function")]
        HRESULT ExchangeData([in] BSTR data);
    };

	[
//...
	]
    interface IMethodTest : IDispatch{

        [id(0x00000010), helpstring("test function")]
        HRESULT SetTaskData([in] LONG type,
                            [in] IMethodToInvoke * method
                            );
    };

After compilation we'll see what we expected in code above.
This is guaranteed by COM technology to provide stable and safe (in some cases) data exchange between applications.
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900