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

__stdcall + extern "C"

572 views
Skip to first unread message

Konstantin Kuzvesov

unread,
Dec 9, 2003, 1:51:13 PM12/9/03
to
I'm trying to use in cpp program external library
with __stdcall fucntions named using wildcard "_*".

When I declare extrenal functions as
extern "C" char *pcap_lookupdev(char *);
and use pragma
#pragma aux pcap_lookupdev "_*";
everything is ok, except that the program doesn't work,
because parameters are passed via registers.

When I declare functions as
__stdcall char *pcap_lookupdev(char *);
there appears compiler
main.cpp(8): Warning! W211: col(32) #pragma attributes for 'pcap_lookupdev' may be inconsistent
and linker errors
Error! E2028: _pcap_lookupdev@4 is an undefined reference

How should I define __stdcall function in cpp file to get correct linking name ?
(without additional @xxx )


Michal Necasek

unread,
Dec 9, 2003, 2:57:55 PM12/9/03
to
Konstantin Kuzvesov wrote:
>> So what symbol does the library have? How do you know the library
>>uses __stdcall?
>
> I compiled program example in C with using __stdcall and it works.
> It cause an exception without __stdcall. => library uses stdcall funcs.
>
That's hardly a proof. How do you know it doesn't use the __system
calling convention for instance? It's quite similar to __stdcall.

Anyway I was wrong, __stdcall does prepend an underscore.

> The problem is that I can't undecorate C++ function names
> when using both extern "C" and __stdcall.
>
My problem is that I still don't know what exactly your problem
is. Please post the exact prototype for the function that you use
and the exact name of the corresponding symbol in the library.

Another question, is it a statically linked library or an import
library?


Michal

Michal Necasek

unread,
Dec 9, 2003, 2:15:09 PM12/9/03
to
Konstantin Kuzvesov wrote:

> I'm trying to use in cpp program external library
> with __stdcall fucntions named using wildcard "_*".
>

Are you sure? That is highly irregular behaviour and goes against how
__stdcall is defined.

> When I declare functions as
> __stdcall char *pcap_lookupdev(char *);
> there appears compiler
> main.cpp(8): Warning! W211: col(32) #pragma attributes for 'pcap_lookupdev' may be inconsistent
>

Of course, since __stdcall specifies how the name should be decorated
and leading underscore is not it.

> and linker errors
> Error! E2028: _pcap_lookupdev@4 is an undefined reference
>

So what symbol does the library have? How do you know the library
uses __stdcall?


Michal

Konstantin Kuzvesov

unread,
Dec 9, 2003, 2:38:20 PM12/9/03
to
> So what symbol does the library have? How do you know the library
> uses __stdcall?

I compiled program example in C with using __stdcall and it works.


It cause an exception without __stdcall. => library uses stdcall funcs.

The problem is that I can't undecorate C++ function names

Konstantin Kuzvesov

unread,
Dec 9, 2003, 10:20:01 PM12/9/03
to
> Another question, is it a statically linked library or an import
> library?
It it an import library (linked to DLL).

I tried to change __stdcall to __system, and compiler said that he doesn't know what it is.
Maybe I don't really know what __stdcall is ? I thought it just defines that parameters
are passed via stack.

How can stack based calling convention be defined for one (or several) functions only ?

Konstantin


Michal Necasek

unread,
Dec 10, 2003, 1:00:17 AM12/10/03
to
Konstantin Kuzvesov wrote:

> Maybe I don't really know what __stdcall is ? I thought it just defines that parameters
> are passed via stack.
>

No, it also defines how the name is decorated. Read the Open Watcom
documentation.

> How can stack based calling convention be defined for one (or several) functions only ?
>

Declare one or more function as __stdcall. Or use #pragma aux to
specify the functions' attributes. Again, see documentation.


Michal

Jim

unread,
Dec 10, 2003, 6:28:56 AM12/10/03
to
perhaps you don't mean stdcall which isn't 'standard' but perhaps __cdecl...
__stdcall also passes the parameters left to right - that is the first
parameter is pushed first... _cdecl pushes the last parameter first - which
allows for things like varargs to work since the first parameter is always
the last on the stack...

--
If there is no spoon...there are no bugs, and there IS no spoon.

"Konstantin Kuzvesov" <kuzv...@list.ru> wrote in message
news:br6370$nsm$1...@www1.scitechsoft.com...

Michal Necasek

unread,
Dec 16, 2003, 12:50:56 PM12/16/03
to
Konstantin Kuzvesov wrote:
> I didn't find how to set up stack-based calling for single function.
> Documentation on #pragma connected to this is poor enough :(
>
You are welcome to contribute better documentation if you think the
current docs are inadequate!

> (I looked in lguide.hlp and cguide.hlp).
>
Look harder. It's right there in cguide.hlp - and yes, there is a LOT
to read.

Take this example describing __cdecl in #pragma aux terms (from
cguide):

#pragma aux __cdecl "_*" \
parm caller [] \
value struct float struct routine [eax] \
modify [eax ecx edx]

The pragma is called __cdecl, adds an underscore; caller removes
arguments from stack, no registers are used for passing arguments;
structs and floats are returned in memory allocated by routine
(pointed to by eax), other values will be returned in eax; routines
may trash eax, ecx and edx. This is all from cguide. I don't remember
all this stuff either.

So if you do:

----------------------------------
#pragma aux _stkcall "_*" \
parm caller [] \
value struct float struct routine [eax] \
modify [eax ecx edx]

int _stkcall foo( int i )
{
return i + 1;
}

int bar( void )
{
int j;

j = foo( 3 );
}
----------------------------------

you will see that foo() takes arguments on stack; see especially
the "32-bit: Alias Names" chapter in cguide for example code.


Michal

Konstantin Kuzvesov

unread,
Dec 12, 2003, 3:12:01 PM12/12/03
to
I didn't find how to set up stack-based calling for single function.
Documentation on #pragma connected to this is poor enough :(
(I looked in lguide.hlp and cguide.hlp).

Using stack-based calling as default calling convention.

Konstantin


Jim

unread,
Dec 16, 2003, 9:12:36 PM12/16/03
to
>
> Using stack-based calling as default calling convention.

I gave up trying to force EVERYTHING to be a 'normal' (normal of course
being relative to whatever you came from) calling convention... just declare
what you need...

but you do understand that just cause things are on the stack, there's still
at least 2 ways to order stuff on the stack?

>
> Konstantin
>
>


Gisle Vanem

unread,
Dec 20, 2003, 3:51:40 PM12/20/03
to
"Konstantin Kuzvesov" <kuzv...@list.ru> wrote:

> I don't know how declare the function to get stack-based calling for the one.
> Briefly, it works with global stack-based calling, and it doesn't work with
> register calling.

You mean with register based calls you need to override a single
function? Here is how I did it (in a -3r compilation):

extern int cdecl foo (int a, int b);

#if defined(__WATCOMC__)
/* No decoration. Args on stack. ECX/EDX not preserved */
#pragma aux (cdecl) foo "_*" modify [ecx edx] parm caller[];
#endif

And in the .asm file:
.386.
.model flat,c
.code
_foo:
... ; save and restore ebx,esi,edi here
; but ecx/edx should be allowed to change
ret

Unfortunately it's not always reliable since OW 1.1+ seems to
not stash away the EDX/ECX registers in some cases (compiled
with -oilrtfm). So I ended up coding foo() in C instead.

--gv

Konstantin Kuzvesov

unread,
Dec 20, 2003, 2:42:11 PM12/20/03
to
> but you do understand that just cause things are on the stack, there's still
> at least 2 ways to order stuff on the stack?

Yes, I understand how parameters are passed via stack.
I'm a bit familiar with assembler.

I don't know how declare the function to get stack-based calling for the one.
Briefly, it works with global stack-based calling, and it doesn't work with
register calling.

Konstantin


0 new messages