Board index » cppbuilder » Borland __cdecl anomaly?

Borland __cdecl anomaly?


2007-10-21 03:27:08 AM
cppbuilder8
 
 

Re:Borland __cdecl anomaly?

Whoops, I clicked the send button before I wrote my post...
My understanding of the __cdecl calling convention is that if a function is expected to return a value where the data structure is 8 bytes or less, then the return value(s) are returned in the eax:edx pair. Otherwise, the calling function uses memory (sending a hidden pointer via an argument push).
I have a situation where this is not happening. I am using a dll what was compiled with msvc++. The dll function that I am calling uses a simple structure:
struct errortag{
byte kind:
DWORD number:
}
typedef errortag error;
error dllfunct(void);
Even thought the header points out that the data structure is less than 8 bytes(the data is returned in EAX:EDX), the Borland TurboC++ compiler still expects the returned data to be returned in memory.
I can find no compiler/linker option that would help fix this.
Does anyone have a suggestion as to fixing this issue?
Thanks for any suggestions
Jim
 

Re:Borland __cdecl anomaly?

Jim Flanagan wrote:
Quote
My understanding of the __cdecl calling convention is that if a function is expected to
return a value where the data structure is 8 bytes or less, then the return value(s)
are returned in the eax:edx pair.
AFAIK, that's not specific to _cdecl.
This is from a very old (16 bit TASM 2.5) Borland manual (parphrased):
Structures are a bit more complex.
Structures that are 1 or 2 bytes are returned in AX.
Structures that are 4 bytes are returned in DX:AX.
Structures that are 3 bytes, or more than 4 bytes are returned via pointer.
So we should expect to expand that to 32 bit-land:
Structures that are 1 to 4 bytes are returned in EAX.
Structures that are 8 bytes are returned in EDX:EAX.
Structures that are 5 to 7 bytes, or more than 8 bytes are returned via pointer.
Your structure is somewhere between 5 and 8 bytes, depending upon
alignment settings. You might try making sure alignment is 4.
If the dll is incompatable, you might write a lightweight wrapper
to forward the registers into the application's structure.
 

{smallsort}

Re:Borland __cdecl anomaly?

Bob Gonder wrote:
Quote
Jim Flanagan wrote:

>My understanding of the __cdecl calling convention is that if a function is expected to
>return a value where the data structure is 8 bytes or less, then the return value(s)
>are returned in the eax:edx pair.

AFAIK, that's not specific to _cdecl.
This is from a very old (16 bit TASM 2.5) Borland manual (parphrased):

Structures are a bit more complex.
Structures that are 1 or 2 bytes are returned in AX.
Structures that are 4 bytes are returned in DX:AX.
Structures that are 3 bytes, or more than 4 bytes are returned via pointer.

So we should expect to expand that to 32 bit-land:

Structures that are 1 to 4 bytes are returned in EAX.
Structures that are 8 bytes are returned in EDX:EAX.
Structures that are 5 to 7 bytes, or more than 8 bytes are returned via pointer.

Your structure is somewhere between 5 and 8 bytes, depending upon
alignment settings. You might try making sure alignment is 4.

If the dll is incompatable, you might write a lightweight wrapper
to forward the registers into the application's structure.

Hi Bob -
Thanks for the response and the information. Using what you mentioned,
I purposely changed the header in an attempt to 'trick' the compiler to
use the eax:edx pair.
struct errortag{
DWORD kind:
DWORD number:
}
typedef errortag error;
error dllfunct(void);
I used the sizeof() function to test the memory size of type error and
it reported 8 bytes. However, again, after examining the compiled
assembly just prior to the call to dllfunct, it still shows using
a pointer, instead of using the eax:edx pair. I'm confused. I guess I
could write the wrapper as you suggested, but it seems that there should
be a more elegant way around this.
By the way, my default data alignment is 8 bytes. I tried 4, but no
difference. Do you have any other suggestions. I certainly appreciate
your help, thanks.
Jim
Quote

 

Re:Borland __cdecl anomaly?

Jim Flanagan wrote:
Quote
Do you have any other suggestions.
Just compiled a test...
typedef __int64 error; // no problem, return register
struct errortag{
__int64 n;
};
typedef struct errortag error; // problem, return pointer
Changed Options/Source/MSVCcompatability(-VM)
No problem, return register
 

Re:Borland __cdecl anomaly?

Bob Gonder wrote:
Quote
Jim Flanagan wrote:

>Do you have any other suggestions.

Just compiled a test...

typedef __int64 error; // no problem, return register

struct errortag{
__int64 n;
};
typedef struct errortag error; // problem, return pointer

Changed Options/Source/MSVCcompatability(-VM)
No problem, return register



Thanks, Bob...
It looks like I'm on the verge of solving this. Unfortunately,
when I try to use the -vm option I get two errors that I don't
know how to handle (as you can tell, I'm pretty new to TurboC++).
Here are my two error messages:
[C++ Error] GUI.cpp(9): E2356 Type mismatch in redeclaration of
'__stdcall WinMain(void *,void *,char *,int)'
[C++ Error] winbase.h(1885): E2344 Earlier declaration of '__stdcall
WinMain(void *,void *,char *,int)'
Not being intimate with the details of windows programming, I don't
understand this error. Why is there a redeclaration going on here?
Hope your patience is still in check, Bob. Right now you are my lifeline...
Jim
 

Re:Borland __cdecl anomaly?

Jim Flanagan wrote:
Quote
Bob Gonder wrote:
>Changed Options/Source/MSVCcompatability(-VM)
It looks like I'm on the verge of solving this. Unfortunately,
when I try to use the -vm option I get two errors that I don't
I don't know off the top of my head what -vm would do to your
compile, but -VM seems to work ok.
Quote
[C++ Error] GUI.cpp(9): E2356 Type mismatch in redeclaration of
'__stdcall WinMain(void *,void *,char *,int)'

[C++ Error] winbase.h(1885): E2344 Earlier declaration of '__stdcall
WinMain(void *,void *,char *,int)'
I don't know why you have a problem there.
I just changed my main to the following, and had no compile errors
(link errors, caused by no _main, but...)
//int main (void)
#pragma argsused
int _stdcall WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow)
{ ... }
Hmmm....you might want to delete your precompiled headers.
You can find the filename of the PCH in the Options.
 

Re:Borland __cdecl anomaly?

"Jim Flanagan" < XXXX@XXXXX.COM >wrote in message
Quote
Here are my two error messages:

[C++ Error] GUI.cpp(9): E2356 Type mismatch in redeclaration of '__stdcall
WinMain(void *,void *,char *,int)'

[C++ Error] winbase.h(1885): E2344 Earlier declaration of '__stdcall
WinMain(void *,void *,char *,int)'

Not being intimate with the details of windows programming, I don't
understand this error. Why is there a redeclaration going on here?
Check the return type. I believe this error may indicate a difference in
return types of two otherwise identical functions.
- Dennis
 

Re:Borland __cdecl anomaly?

Quote

Hmmm....you might want to delete your precompiled headers.
You can find the filename of the PCH in the Options.


Thanks, Bob...
That did it!! I rebuilt the headers and that
resolved the error. Now I can get back to doing
real work as my app now appears compatible
with the MSVC++ DLL.
I guess it is all part of the game.
I certainly appreciate you{*word*154} in there for me.
Take care...
Jim