Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

__stdcall into __cdecl

140 views
Skip to first unread message

justapr...@gmail.com

unread,
Aug 23, 2005, 6:37:18 AM8/23/05
to
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?

Regards
David


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Marco Manfredini

unread,
Aug 23, 2005, 9:46:29 AM8/23/05
to
justapr...@gmail.com wrote:

> 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 ]

Heinz Ozwirk

unread,
Aug 23, 2005, 9:46:54 AM8/23/05
to
<justapr...@gmail.com> schrieb im Newsbeitrag
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)?

_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

Ismail Pazarbasi

unread,
Aug 23, 2005, 10:51:22 AM8/23/05
to
I don't think so. The problem is with "thiscall" and "cdecl", actually.
You provide a non-static member function to a C function. Function
expects a cdecl function. From EH.H:51

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

Stefan Näwe

unread,
Aug 23, 2005, 10:52:29 AM8/23/05
to
justapr...@gmail.com wrote:
> 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?

You want to make Win32Exception::trans_func() a 'free
standing' function.

Stefan

ulrich

unread,
Aug 23, 2005, 11:10:06 AM8/23/05
to
On 23 Aug 2005 06:37:18 -0400, <justapr...@gmail.com> wrote:

> 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,

Paul Shpilsher

unread,
Aug 24, 2005, 4:07:49 AM8/24/05
to
{Please try to avoid top-posting -mod}

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 ]

justapr...@gmail.com

unread,
Aug 24, 2005, 10:57:12 AM8/24/05
to
Oops - here is the native that caused all the trouble
A::A()
{
int i = 0;
int j = 1/i;

justapr...@gmail.com

unread,
Aug 24, 2005, 11:02:39 AM8/24/05
to
Thanks for all the comments. Putting them together for those interested
this is what I wanted:

// 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

0 new messages