Here is my prototype code:
class Win32Exception
{
public:
void init() {
_set_se_translator( Win32Exception::trans_func);
}
Win32Exception();
virtual ~Win32Exception();
private:
void trans_func( unsigned int u, EXCEPTION_POINTERS* pExp )
{
throw std::runtime_error("In trans_func.");
}
};
The proble comes is that I think the class provides a __stdcall but C++
requires a __cdecl. reinterpret_cast does not work (seems reasonable to
me)?
What do I do?
Regards
David
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
> The proble comes is that I think the class provides a __stdcall but
> C++ requires a __cdecl. reinterpret_cast does not work (seems
> reasonable to me)?
The problem is, that you use a member function where a function pointer
is required. There is nothing to cast anyway.
You should try this instead:
static void __stdcall trans_func( unsigned int u,
EXCEPTION_POINTERS* pExp )
{
throw std::runtime_error("In trans_func.");
}
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
_set_se_translator expects a pointer to a (global) function, not a member
function of some class. And you cannot convert a pointer to a
member-function to a simple function pointer.
HTH
Heinz
typedef void (__cdecl *_se_translator_function)(unsigned int, struct
_EXCEPTION_POINTERS*);
trans_func is void __thiscall Win32Exception::trans_func(unsigned int,
EXCEPTION_POINTERS*);
Try to put "static" qualifier at the beginning of declaration of
trans_func, you may also need to explicitly declare cdecl calling
convention as well (I'm not really sure).
In fact, you don't need Win32Exception class at all, I guess. I didn't
know _set_se_translator so far, but I checked it out right now, and it
seems it calls a "function" with "cdecl" convention. You could use the
same example in _set_se_translator's documentation. The example in the
doc is:
#include <stdio.h>
#include <windows.h>
#include <eh.h>
void SEFunc();
void trans_func( unsigned int, EXCEPTION_POINTERS* );
class SE_Exception
{
private:
unsigned int nSE;
public:
SE_Exception() {}
SE_Exception( unsigned int n ) : nSE( n ) {}
~SE_Exception() {}
unsigned int getSeNumber() { return nSE; }
};
int main( void )
{
try
{
_set_se_translator( trans_func );
SEFunc();
}
catch( SE_Exception e )
{
printf( "Caught a __try exception with SE_Exception.\n" );
}
}
void SEFunc()
{
__try
{
int x, y=0;
x = 5 / y;
}
__finally
{
printf( "In finally\n" );
}
}
void trans_func( unsigned int u, EXCEPTION_POINTERS* pExp )
{
printf( "In trans_func.\n" );
throw SE_Exception(); // change here??
}
I think you could simply change "throw SE_Exception()" part to "throw
std::runtime_error" if you like.
Ismail
You want to make Win32Exception::trans_func() a 'free
standing' function.
Stefan
> I am experimenting with a class to deal with Win32 exceptions:
>
> Here is my prototype code:
> class Win32Exception
> {
> public:
> void init() {
> _set_se_translator( Win32Exception::trans_func);
> }
>
> Win32Exception();
>
> virtual ~Win32Exception();
>
> private:
> void trans_func( unsigned int u, EXCEPTION_POINTERS* pExp )
> {
> throw std::runtime_error("In trans_func.");
> }
> };
>
> The proble comes is that I think the class provides a __stdcall but C++
> requires a __cdecl. reinterpret_cast does not work (seems reasonable to
> me)?
>
> What do I do?
i use this
typedef void (*TranslatorFct)(unsigned int, struct _EXCEPTION_POINTERS* );
for the pointer to the translator function, it should hold the address of
your trans_func().
further, my equivalent of your trans_func() and init() are static methods
of the class.
no __cdecl or __stdcall stuff is required.
regards,
Just declare
class Win32Exception
{
....
....
private:
static void __cdecl trans_func( unsigned int u, EXCEPTION_POINTERS*
pExp )
{
throw std::runtime_error("In trans_func.");
}
};
<justapr...@gmail.com> wrote in message
news:1124784300.0...@g14g2000cwa.googlegroups.com...
>I am experimenting with a class to deal with Win32 exceptions:
>
> Here is my prototype code:
> class Win32Exception
> {
> public:
> void init() {
> _set_se_translator( Win32Exception::trans_func);
> }
>
> Win32Exception();
>
> virtual ~Win32Exception();
>
> private:
> void trans_func( unsigned int u, EXCEPTION_POINTERS* pExp )
> {
> throw std::runtime_error("In trans_func.");
> }
> };
>
> The proble comes is that I think the class provides a __stdcall but C++
> requires a __cdecl. reinterpret_cast does not work (seems reasonable to
> me)?
>
> What do I do?
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
// main.cpp
#include <iostream>
#include "A.h"
#include "Win32Exception.h"
int main(int argc, char* argv[])
{
try{
Win32Exception r;//This is not nice but not too important.
//I was hoping "catch (Win32Exception &e)"
//would invoke init().
A a; //Throws a divide by zero exception.
}catch (std::logic_error&e){
//Don't want this
std::cout <<"logic_error=" << e.what() << std::endl;
}catch (std::runtime_error&e){
//Don't want this
std::cout <<"runtime_error="<< e.what() << std::endl;
}catch (Win32Exception &e){
//Want this
std::cout <<"Win32Exception="<< e.what() << std::endl;
}catch (std::exception&e){
//Don't want this
std::cout <<"Vanilla="<< e.what() << std::endl;
}catch (...){
//This is a complete disaster
std::cout <<"..."<< std::endl;
}
return 0;
}
and then
// Win32Exception.h
#if !defined(WIN32EXCEPTION_H)
#define WIN32EXCEPTION_H
#include <stdexcept>
struct _EXCEPTION_POINTERS;
typedef _EXCEPTION_POINTERS EXCEPTION_POINTERS;
class Win32Exception : public std::exception
{
public:
Win32Exception(const char *);
Win32Exception();
virtual ~Win32Exception();
inline void init();
private:
inline static void __cdecl trans_func( unsigned int u,
EXCEPTION_POINTERS* pExp );
};
#endif
and finally
// A.h
#if !defined(A__H)
#define A__H
class A
{
public:
A();
virtual ~A();
};
#endif