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

linking dll with g95

47 views
Skip to first unread message

acp693

unread,
Jun 29, 2009, 2:20:52 PM6/29/09
to
Hello, I've been trying to link a dll with a simple test program using
g95.

I have the code working using Silverfrosts FTN95 compiler however I
wish to use the open source GNU g95 compiler

My code looks like this for the FTN95 compiler:

program testfoo
implicit none
STDCALL foof_MP_foo 'foof_MP_foo' (ref,ref,ref)
integer :: a, b, c
a=2
b=3
call foof_MP_foo(a,b,c)
print*, c

end program testfoo

and I compile and link using:

>ftn95 testfoo /import_lib foo.dll

What changes do I have to make to the source code to compile and link
with g95?
and what commands do I need to compile and link?

I tried to compile the original source code with the following:

>g95 -o testfoo testfoo.f95 -L -lfoo.dll

I receive the following error message
In file testfoo.f95:3

STDCALL foof_MP_foo 'foof_MP_foo' (ref,ref,ref)
1
Error: Unclassifiable statement at (1)

Can anyone help a Fortran newbie on his way with this?

Thanks

Albert Harris


e p chandler

unread,
Jun 29, 2009, 2:41:43 PM6/29/09
to

There is no provision in the Fortran standard for specifying calling
conventions. STDCALL is specific to a particular compiler. Other
compilers may have similar directives - IIRC Lahey, Watcom and MS/DEC/
Compaq/Intel do have ways of specifying this in the source code.

The GCC family does not have such a provision. It does have the -mrtd
command line option. Note that this option applies to all code
compiled with that command line. I have not tried it in compiling code
that calls other code previously compiled with the STDCALL convention.
I have used it to compile a DLL which is called by Visual Basic/VBA/
Delphi, etc.

--- e

steve

unread,
Jun 29, 2009, 3:11:18 PM6/29/09
to

As of subversion revision 149036, gfortran has a mechanism for specify
the calling convention.

http://gcc.gnu.org/onlinedocs/gfortran/GNU-Fortran-Compiler-Directives.html#GNU-Fortran-Compiler-Directives

acp693

unread,
Jun 29, 2009, 3:25:58 PM6/29/09
to

> > There is no provision in the Fortran standard for specifying calling
> > conventions. STDCALL is specific to a particular compiler. Other
> > compilers may have similar directives - IIRC Lahey, Watcom and MS/DEC/
> > Compaq/Intel do have ways of specifying this in the source code.
>
> > The GCC family does not have such a provision. It does have the -mrtd
> > command line option.
>
> As of subversion revision 149036, gfortran has a mechanism for specify
> the calling convention.
>
> http://gcc.gnu.org/onlinedocs/gfortran/GNU-Fortran-Compiler-Directive...

Thanks e p chandler and steve, However I'm still at a loss as to how I
should modify my code and compile commands

Regards

Albert Harris

acp693

unread,
Jun 29, 2009, 3:42:22 PM6/29/09
to
Okay, I got it working.

I removed the following line from the source code:

STDCALL foof_MP_foo 'foof_MP_foo' (ref,ref,ref)

and then compiled with:

>g95 -mrtd -fno-underscoring testfoo.f95 -o testfoo -Wl,foo.dll

Thanks again e p Chandler and steve.

Regards

Albert

e p chandler

unread,
Jun 29, 2009, 4:00:31 PM6/29/09
to

I'm happy that it worked for you. I would be cautious that using "-
mrtd" might have some unseen effects.

The revision to gfortran to use

!GCC$ ATTRIBUTES....

that Steve Kargl mentions is an *interesting* choice, as it extends
the MS/DEC/CVF/Intel directives. Perhaps Andy will consider it for
g95?

For the OP and others, I did not distinguish enough between caller and
called program in my post.

Specifying the calling convention in the interface to a sub program
should allow calling the Windows API on 32 bit Windows directly from
gfortran.

Specifying the interface that a procedure exports to a program that
calls it would help in creating a library or DLL that contains
routines called by CDECL mixed with routines called by STDCALL, for
example.

-- e

albert

unread,
Jun 30, 2009, 2:25:47 AM6/30/09
to

thanks e p chandler for your comment. I found that it also works
without the -mrdt command.

regards Albert

Tobias Burnus

unread,
Jun 30, 2009, 3:10:12 AM6/30/09
to
On 30 Jun., 08:25, albert <acp...@freenet.de> wrote:
> thanks e p chandler for your comment. I found that it also works
> without the -mrdt command.

Well, that is then only by change. By default ("CDECL"), when calling
a procedure (subroutine or function), the arguments are put on the
stack - and after the callee has finished, the caller pops the
arguments from the stack:

program testfoo
[...]
! do the "call foof_MP_foo(a,b,c)"
-> push a,b,c to the stack
-> jump to "foof_MP_foo"
subroutine foofMP_foo(a,b,c)
-> use the arguments and do something
-> return
-> (in program testfoo) pop the arguments from the stack.


Using STDCALL, the callee pops the arguments from the stack:

program testfoo
[...]
! do the "call foof_MP_foo(a,b,c)"
-> push a,b,c to the stack
-> jump to "foof_MP_foo"
subroutine foofMP_foo(a,b,c)
-> use the arguments and do something
-> (in subroutine foofMP_foo) pop the arguments from the stack.
-> return


In 32bit Windows the function names are additionally decorated:
For CDECL, a leading "_" is added (unless I am mistaken)
For STDCALL a @<n> is added, where <n> denotes the byte size of
the arguments on the stack


That means in GCC/gfortran/g95:

- With default options, CDECL is used and the caller pops the
arguments from the stack
- With -mrdt, by default STDCALL is used where the callee pops the
arguments from the stack
- Using the CDECL or STDCALL the calling conventions can be changed
per procedure (pointer) basis

Note: CDECL is only useful when using -mrdt as otherwise it is already
the default; I have heard that -mrdt does not add the @<n> decoration
while the STDCALL attribute does.

None 2: For 64bit Windows, CDECL is the default - also for the Windows
API DLLs.

Note 3: The problem of using -mrdt is that this uses the STDCALL
calling convention for all calls in that file, which is often not
correct; usually most of the calls should be CDECL and only a few (to
the Win32 ABI) should be using STDCALL.

Using the very recently (last Sunday!) added attribute support in
gfortran, your program would look like:

program testfoo
implicit none
interface
subroutine foof_MP_foo(a,b,c) bind(C,name='foof_MP_foo')
integer :: a, b, c
!GCC$ ATTRIBUTES STDCALL :: foof_MP_foo
end interface

integer :: a, b, c
a=2
b=3
call foof_MP_foo(a,b,c)
print*, c
end program testfoo


Tobias

Disclaimer: While I looked into the problem for gfortran, I have not
tested it under Windows and I have almost no Windows programming
experience.

Craig Powers

unread,
Jun 30, 2009, 1:21:47 PM6/30/09
to
Tobias Burnus wrote:
>
> None 2: For 64bit Windows, CDECL is the default - also for the Windows
> API DLLs.

The latter point is potentially misleading. The default calling
convention for Win32 APIs is stdcall, not cdecl.

James Van Buskirk

unread,
Jun 30, 2009, 8:34:39 PM6/30/09
to
"Craig Powers" <craig....@invalid.invalid> wrote in message
news:h2dhp2$208$1...@news.eternal-september.org...

> Tobias Burnus wrote:

Not that misleading. For 64-bit Windows stdcall and cdecl are
indistinguishable.

--
write(*,*) transfer((/17.392111325966148d0,6.5794487871554595D-85, &
6.0134700243160014d-154/),(/'x'/)); end


Catherine Rees Lay

unread,
Jul 1, 2009, 4:43:31 AM7/1/09
to
albert wrote:
>
> I found that it also works
> without the -mrdt command.
>

You should make sure you use the right version though. Often specifying
the "wrong" calling convention will appear to work but fail somewhere
completely different much later on in the program, or on the seventeenth
time you call it, or when there's a J in the month, or on your client's
computer, when it works just fine on yours...

Learnt that from painful experience :)

Catherine.
--
Catherine Rees Lay

Polyhedron Software Ltd. Registered Office: Linden House,
93 High St, Standlake, Witney, OX29 7RH, United Kingdom.
Registered in England No.2541693. Vat Reg No. GB 537 3214 57

Arjen Markus

unread,
Jul 1, 2009, 5:55:46 AM7/1/09
to
On 1 jul, 10:43, Catherine Rees Lay <catherine.n...@polyhedron.com>
wrote:

>
> Learnt that from painful experience :)
>
> Catherine.

Luckily, you can still smile.

Regards,

Arjen

Craig Powers

unread,
Jul 1, 2009, 11:18:18 AM7/1/09
to
James Van Buskirk wrote:
> "Craig Powers" <craig....@invalid.invalid> wrote in message
> news:h2dhp2$208$1...@news.eternal-september.org...
>
>> Tobias Burnus wrote:
>
>>> None 2: For 64bit Windows, CDECL is the default - also for the Windows
>>> API DLLs.
>
>> The latter point is potentially misleading. The default calling
>> convention for Win32 APIs is stdcall, not cdecl.
>
> Not that misleading. For 64-bit Windows stdcall and cdecl are
> indistinguishable.

Sure, it's fine for Win64, but I thought 32-bit had been discussed in
the thread as well.

dpb

unread,
Jul 1, 2009, 11:21:09 AM7/1/09
to
James Van Buskirk wrote:
...

> Not that misleading. For 64-bit Windows stdcall and cdecl are
> indistinguishable.

Does the responsibility for stack cleanup change as well between 32- and
64-bit Windows? That seems bizarre if so...

--

James Van Buskirk

unread,
Jul 1, 2009, 1:32:17 PM7/1/09
to
"dpb" <no...@non.net> wrote in message
news:h2fv92$t9n$2...@news.eternal-september.org...

> James Van Buskirk wrote:

>> Not that misleading. For 64-bit Windows stdcall and cdecl are
>> indistinguishable.

> Does the responsibility for stack cleanup change as well between 32- and
> 64-bit Windows? That seems bizarre if so...

Caller always cleans up in x64. The stack comes to the callee aligned
8 mod 16. Caller is responsible for creating the 32-byte parameter
save area just above the return address. See
http://www.agner.org/optimize/calling_conventions.pdf for a concise
comparison of calling conventions.

dpb

unread,
Jul 1, 2009, 3:31:45 PM7/1/09
to
James Van Buskirk wrote:
...
> Caller always cleans up in x64. The stack comes to the callee aligned
> 8 mod 16. Caller is responsible for creating the 32-byte parameter
> save area just above the return address. See
> http://www.agner.org/optimize/calling_conventions.pdf for a concise
> comparison of calling conventions.

OK, I'm showing my ignorance here... :)

I thought there was something inherent in C about callee cleaning up and
the Win32 API stdcall was an aberration????

--

Craig Powers

unread,
Jul 1, 2009, 5:17:23 PM7/1/09
to

stdcall causes problems with C varargs. With cdecl, nothing special is
required because the caller knows how much was sent in and how much
needs to be cleaned up off the stack, whereas with stdcall it would be
necessary to do something to let the callee know how much to clean (e.g.
a hidden length argument).

dpb

unread,
Jul 1, 2009, 5:47:03 PM7/1/09
to

I suppose the C/C++ Standard like the Fortran one doesn't address the
"how" an implementation manages its business?

I was just surprised that what I thought was traditional in C owing to
the language syntax would go away and seem to me in my ignorance to
cause widespread incompatibilities in C code by switching from "callee
cleans up" to "caller does so".

Or, given my level of unfamiliarity, perhaps I just don't understand; I
can believe that, too... :)

--

nm...@cam.ac.uk

unread,
Jul 1, 2009, 6:38:01 PM7/1/09
to
In article <h2glsr$a70$1...@news.eternal-september.org>,

dpb <no...@non.net> wrote:
>Craig Powers wrote:
>> dpb wrote:
>>> James Van Buskirk wrote:
>>> ...
>>>> Caller always cleans up in x64. The stack comes to the callee aligned
>>>> 8 mod 16. Caller is responsible for creating the 32-byte parameter
>>>> save area just above the return address. See
>>>> http://www.agner.org/optimize/calling_conventions.pdf for a concise
>>>> comparison of calling conventions.
>>>
>>> OK, I'm showing my ignorance here... :)
>>>
>>> I thought there was something inherent in C about callee cleaning up
>>> and the Win32 API stdcall was an aberration????

No, there isn't. That is part of the justification for the unnecessary
restrictions on setjmp/longjmp.

>> stdcall causes problems with C varargs. With cdecl, nothing special is
>> required because the caller knows how much was sent in and how much
>> needs to be cleaned up off the stack, whereas with stdcall it would be
>> necessary to do something to let the callee know how much to clean (e.g.
>> a hidden length argument).
>
>I suppose the C/C++ Standard like the Fortran one doesn't address the
>"how" an implementation manages its business?

In theory, that is correct. In practice, it is less so.

>I was just surprised that what I thought was traditional in C owing to
>the language syntax would go away and seem to me in my ignorance to
>cause widespread incompatibilities in C code by switching from "callee
>cleans up" to "caller does so".

Any program that can tell the difference is relying on undefined
behaviour. But - hey! - ALL realistic C programs have to do that.
However, this is generally considered to be undefined behaviour
of the sort that indicates that the program is broken.


Regards,
Nick Maclaren.

0 new messages