[vc++] COM callback geeft fout onder Excel

Pagina: 1
Acties:

Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Ben al een tijdje bezig met een objectje te maken dat je vanuit excel moet kunnen aanroepen/gebruiken. Op zich werkt het geheel, echter heb ik een callback nodig.

Het probleem ligt hem erin dat de callback functie een cdecl functie is, welke natuurlijk niet zo gebruikt kan worden in VBA. Volgens MS Hier schrijven we MS moet je een wrapper functie bouwen om dit probleem te omzeilen.

Echter wat is het geval, ik heb een wrapper functie gebouwd welke dus mijn vba functie aanroept. Het aanroepen ansich gaat goed, maar nadat de vba functie klaar is krijg ik een c++ debug error. Klaarblijkelijk gaat er toch iets niet goed met de calling convention...

Debug error:
code:
1
Run-Time Check Failure #0 - The value of ESP was not properly saved across a function call. This usually a result of calling a function declared with one calling convention with a function pointer declared with a different calling convention.



edit: (voor deze of gene met rare vragen omtrent pVal)
code:
1
[id(79), helpstring("method SetExceptionHandler")] HRESULT SetExceptionHandler([in] INT pExceptionHandler, [out,retval] VARIANT_BOOL* pVal);


C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
typedef VOID   (__cdecl *DBL_pFuncExceptionHandler)(INT dwErrorCode, VARIANT_BOOL blIsFatal);
typedef LPVOID (__cdecl *tDBL_SetExceptionHandler)(DBL_pFuncExceptionHandler pExceptionHandler);

typedef void (__stdcall CF_pFuncExceptionHandler)(INT dwErrorCode, VARIANT_BOOL blIsFatal);
CF_pFuncExceptionHandler* Raise_ExceptionHandler;

STDMETHODIMP CCFRONT::SetExceptionHandler(INT pExceptionHandler, VARIANT_BOOL* pVal)
{
    if (CHECKFUNCPTR(DBL_SetExceptionHandler))
    {
        if (DBL_SetExceptionHandler(&Callback_ExceptionHandler) != NULL)
        {
            Raise_ExceptionHandler = reinterpret_cast<CF_pFuncExceptionHandler*>(pExceptionHandler);
            *pVal = TRUE;
        }
        *pVal = FALSE;
        return S_OK;
    }
    return E_NOTIMPL;
}

VOID __cdecl Callback_ExceptionHandler(INT dwErrorCode, VARIANT_BOOL blIsFatal)
{
    if (Raise_ExceptionHandler != NULL)
    {
        // Hieronder gaat het fout...
        Raise_ExceptionHandler(dwErrorCode, blIsFatal);
    }
}


De code ansich lijkt gewoon goed gaan, want als ik dit doe in C#, dan gaat het gewoon goed.

C#:
1
2
3
4
5
6
7
8
9
10
delegate void DBL_pFuncExceptionHandler(int dwErrorCode, bool blIsFatal);

public static void Test()
{
    cf.SetExceptionHandler(Marshal.GetFunctionPointerForDelegate(new DBL_pFuncExceptionHandler(cf600_ExceptionHandler)).ToInt32());
}

public static void cf600_ExceptionHandler(int dwErrorCode, bool blIsFatal)
{
}


Hier mijn vba code:
Visual Basic:
1
2
3
4
5
6
7
Private Function Test()
    cf.SetExceptionHandler(AddressOf CFRONT_ExceptionHandler)
End Function

Private Function CFRONT_ExceptionHandler(ByVal dwErrorCode As Long, ByVal blIsFatal As Boolean)
    MsgBox "blaat"
End Function



Het is idd niet de beste code die je kan schrijven, een int doorgeven als function pointer. Misschien dat daar ook wel de basis ligt van het probleem, het frapante is dat het wel goed werkt onder C#. Helaas ben ik gebonden aan een library die cdecl gebruikt en excel dat alleen stdcall aankan. Suggesties zijn natuurlijk altijd welkom :D

Ik heb al wel naar connection points gekeken, echter wil ik alleen een exception handler setten als er ook daadwerkelijk ééntje geset wordt vanuit vba. En ik ben nog niet in staat geweest om dit werkend te krijgen onder vba...vraag me uberhaupt af of dit wel mogelijk is.

Ik hoop dat iemand mij in de juiste richting kan sturen...ik zie namelijk niet goed wat er nou eigenlijk fout gaat... Ik heb een sterk vermoeden, maar ik snap dan niet goed wat er fout is aan mijn code.

[ Voor 3% gewijzigd door RobIII op 15-06-2009 18:33 . Reden: M$ :| ]


Acties:
  • 0 Henk 'm!

  • farlane
  • Registratie: Maart 2000
  • Laatst online: 17:02
Waarom gebuik je geen event voor de callback naar Excel? ( Dwz, gebruik de exceptionhandler lokaal in je object en raise vanuit daar een event )

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Events...managed wordt hem sowieso niet. En atl events, ik wil alleen de event handler setten als SetExceptionHandler aangeroepen wordt, anders moet de standaard exception handler van de C/FRONT C library gebruikt worden. Deze exception handler kan ik niet wijzigen/inzien. So far heb ik vanmiddag en nu net ffies geen hits gevonden op hoe ik een atl event handler zo moet bouwen dat ik kan detecteren wanneer een event ge-attached wordt. Sowieso zag ik niks van deze events terug in vba, toen ik vanmiddag deze connection points geimplementeerd had, overigens wel vanuit c#.

Misschien dat ik je verkeerd begrijp?


Edit:
ben net weer ff bezig geweest, weet al waar het aan ligt.
Is weer een stom iets van Excel/Vb(a).

Een function verwacht iets terug, een sub niet. Dus m'n exceptionhandler als sub definieren ipv function, en alle problemen zijn verdwenen...

Hoe moeilijk kan je het soms maken |:( |:( |:(

[ Voor 31% gewijzigd door Verwijderd op 15-06-2009 23:47 . Reden: Oplossing gevonden ]