soccer jersey forums.silverfrost.com :: View topic - Passing INTEGER*2 arguments using STDCALL convention fails
forums.silverfrost.com Forum Index forums.silverfrost.com
Welcome to the Silverfrost forums
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Passing INTEGER*2 arguments using STDCALL convention fails
Goto page Previous  1, 2
 
Post new topic   Reply to topic    forums.silverfrost.com Forum Index -> Support
View previous topic :: View next topic  
Author Message
sparge



Joined: 11 Apr 2005
Posts: 371

PostPosted: Wed Jun 15, 2011 4:37 pm    Post subject: Re: Reply with quote

davidb wrote:
Actually, however, the Fortran standard doesn't say that arguments must be passed by reference, only that it must appear like that.


Does the FORTRAN standard say that enclosing an argument in brackets "causes a temporary variable to be created which is passed by reference (usually)?"
Back to top
View user's profile Send private message Send e-mail
davidb



Joined: 17 Jul 2009
Posts: 560
Location: UK

PostPosted: Wed Jun 15, 2011 6:10 pm    Post subject: Re: Reply with quote

sparge wrote:

Does the FORTRAN standard say that enclosing an argument in brackets "causes a temporary variable to be created which is passed by reference (usually)?"


I don't think the standard says this explicitly (I don't think I said it did). Its up to the compiler vendor how they implement passing of arguments.

If the vendor opts to pass by reference (most, maybe all, do), then they also need to provide a mechanism to deal with actual arguments which are:

(1) literal constants, e.g. call foo(10.0)
(2) Expressions, e.g. call foo(a*b+c)
(3) Array sections which are non contiguous in memory

Vendors can treat a single variable name in brackets as an expression if they wish and use whatever mechanism they have in place to deal with expressions, or they can ignore/remove the bracket and use the mechanism for passing a variable.

I was merely pointing out (above) that I can get around a bug in the compiler by putting an argument in brackets. I have no idea how this is working, however, given that

(1) Paul still hasn't confirmed there is a bug.
(2) Paul says FTN95 always passes by references, but I have some C++ code which receives a variable by value and I can manage to call it correctly.
Back to top
View user's profile Send private message
PaulLaidler
Site Admin


Joined: 21 Feb 2005
Posts: 7938
Location: Salford, UK

PostPosted: Thu Jun 16, 2011 7:16 am    Post subject: Reply with quote

I did not intend to imply that
Quote:
FTN95 code always needs to pass values by reference to DLLs


Subroutines in an FTN95 DLL can only admit/receive arguments that are passed by reference.

An FTN95 main program etc. can call subroutines in a third party dll (or an SCC dll) and in this situation the arguments can be sent/passed by value.
Back to top
View user's profile Send private message AIM Address
sparge



Joined: 11 Apr 2005
Posts: 371

PostPosted: Thu Jun 16, 2011 9:47 am    Post subject: Third time lucky? Reply with quote

qt wrote:
... the WinAPI/ODBC function SQLBindCol whose second argument requires a short unsigned integer to be passed ...

(italics mine) Just reading this thread again ... FORTRAN has no concept of unsigned, I didn't register that keyword originally. I never understood the significance of the distinction in C i.e. I don''t understand how a compiler treats an integer differently depending if it is signed or unsigned ... but presumably that function would know and complain (or malfunction and suffer in silence) if it was passed a signed short integer from C code. Why would we expect it to work correctly if it gets a signed short integer from FORTRAN code?
Back to top
View user's profile Send private message Send e-mail
IanLambley



Joined: 17 Dec 2006
Posts: 490
Location: Sunderland

PostPosted: Thu Jun 16, 2011 12:32 pm    Post subject: Reply with quote

Surely an unsigned integer can give a value between 0 & 255 or 0 and 65535 depending on whether it is one byte or two byte version. The fortan 1 and two byte integers are signed, with the highest bit being the sign bit and can represent numbers between -128 and +127 or -32768 and +32767 respectively. If you want a single byte version, then use transfer or equivalence e.g.
Code:

integer*2 itwobyte
integer*1 ionebyte(20)
equivalence (itwobyte,ionebyte)
!put a value into the two byte in the range 0 to 255
itwobyte = 255
!use the low byte which is an unsigned integer, but fotran will not treat it as such
!but you should be able to pass it to a C++ routine and that will treat it as unsigned.
print *,ionebyte(1)


The two byte unsigned version
Code:

integer*4 ifourbyte
integer*3 itwobyte(20)
equivalence (ifourbyte,itwobyte)
!put a value into the four byte in the range 0 to 32767
ifourbyte = 32767
!use the low word which is an unsigned integer, but fotran will not treat it as such
!but you should be able to pass it to a C++ routine and that will treat it as unsigned.
print *,itwobyte(1)

and of course integer*8 and integer*4 if needed.
Ian
PS try the transfer method yourself - I still live in the ark!
Back to top
View user's profile Send private message Send e-mail
davidb



Joined: 17 Jul 2009
Posts: 560
Location: UK

PostPosted: Thu Jun 16, 2011 12:39 pm    Post subject: Reply with quote

If we consider shorts (16 bit integers), the range of possible signed shorts is -32768 to 32767; whereas the range of possible unsigned shorts is 0 to 65535.

If you know your integers will always be zero or positive, and may exceed 32767 (but always be less than or equal too 65535) then you would use unsigned shorts. However, if you just want to loop over a list 1 to 1000 it would not matter which you use (aside from providing a visual clue to the programmer than an integer is non-negative).

I assume in the original DLL call the OP would just pass a signed integer of the appropriate value. To pass a value n > 32767, then a negative value
(32767 - n) would need to be passed.

PS. Or use Ian's equivalence method or transfer (but I would just use the subtraction method)
Back to top
View user's profile Send private message
PaulLaidler
Site Admin


Joined: 21 Feb 2005
Posts: 7938
Location: Salford, UK

PostPosted: Tue Aug 02, 2011 11:25 am    Post subject: Reply with quote

My initial test for this issue is as follows

C function...

Code:
#include <stdio.h>
extern "C" void __stdcall PassIntegers(char i1Arg, short i2Arg, int i3Arg)
{
  printf("%d\n", i1Arg);
  printf("%d\n", i2Arg);
  printf("%d\n", i3Arg);
}


Fortran program...

Code:
program test
 STDCALL PassIntegers 'PassIntegers'(VAL,VAL,VAL)
 integer*1 i1
 integer*2 i2
 integer*4 i3
 i1 = 7
 i2 = 45
 i3 = 19
 call PassIntegers(i1,i2,i3)
end program test


This works OK and I don't know how I can progress from here.

When you compile a function/subroutine using FTN95, arguments are always passed (in) by reference but you can pass arguments (out) by value from FTN95 when the function/subroutine is compiled using some other compiler such as SCC.
Back to top
View user's profile Send private message AIM Address
dmcc_ies



Joined: 09 Dec 2011
Posts: 4

PostPosted: Fri Mar 02, 2012 11:47 am    Post subject: Reply with quote

When attempting to pass an int*2 (val, stdcall), does the ftn95 compiler simply promote this to an int*4 and pass this instead?
Back to top
View user's profile Send private message
PaulLaidler
Site Admin


Joined: 21 Feb 2005
Posts: 7938
Location: Salford, UK

PostPosted: Fri Mar 02, 2012 5:03 pm    Post subject: Reply with quote

Yes. If you look at the /explist produced by program test above, then this appears to be the case.
Back to top
View user's profile Send private message AIM Address
Display posts from previous:   
Post new topic   Reply to topic    forums.silverfrost.com Forum Index -> Support All times are GMT + 1 Hour
Goto page Previous  1, 2
Page 2 of 2

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group