- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hello
My task is it the replace a dll written in C which is called from fortran.
In the documentation the fortran declation of the subroutine is:
SUBROUTINE GUREC(LDR, DATREC, IIl, IRL, ERRIND, IL, IA, RL, RA, SL, LSTR, STR) INTEGER LDR CHARACTER*80 DATREC(LDR) INTEGER IIL INTEGER IRL INTEGER ISL INTEGER ERRIND INTEGER IL INTEGER IA(IIL) INTEGER RL INTEGER RA(ISL) INTEGER SL, INTEGER LSTR(ISL) CHARACTER*(*) STR(*)
How must I define the c function?
Especially the definiton of the last parameter STR is not clear.
Is this definition correct?
_declspec(dllexport) void GUREC(int *ldr, char(*datrec)[80], int *iil, int *irl, int *isl, int *errind, int *il, int *ia, int *rl, float *ra, int *sl, int *lstr, char *str, int str_len);
Thanks for Your answer.
Urs
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Short answer: no.
Longer answer: In Fortran 2008, CHARACTER(*) is not interoperable with C. In general, character arguments are problematic because Fortran compilers pass character lengths in different ways. Having an array of character values is even more of a problem. Also, you don't know that Fortran INTEGER is compatible with C int.
It is not really clear to me what you are asking. Do you have an existing Fortran procedure you want to rewrite in C? Are you asking how to call a C routine from Fortran?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I want to rewrite a C routine which is called from Fortran and I don't have the source.
To only documentation that I have, is the specified Fortran declaration.
I am not completely shure how to call C routine from Fortran. In 32 Bit isn't INTEGER compatible with C int?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
There are many ways of doing what you described; the more robust and portable you want the solution to be, the more reading you need to do and the more elaborate the code. The following is an error-prone but compact solution if your Fortran and C are for 32-bit Windows, and you are using Intel Fortran + Intel or MS C. The code assumes lots of things about the representations of variable types and calling conventions, which you will need to understand and document if you take this route. The way that the array of strings is handled is particularly bad, but it may work for now.
The Fortran driver for the C subroutine:
Program CallGUREC implicit none INTEGER, Parameter :: LDRM = 5, ISLM = 3, IILM = 4 CHARACTER(len=80):: DATREC(LDRM) INTEGER LDR, IIL, IRL, ISL, ERRIND, IL, RL, SL INTEGER :: IA(IILM), RA(ISLM), LSTR(ISLM) CHARACTER(len=17) :: STR(7) ! LDR = 3 IIL = 31 IRL = 15 ERRIND = 0 STR(3) = 'This is string 3'C Call Gurec(LDR, DATREC, IIl, IRL, ERRIND, IL, IA, RL, RA, SL, LSTR, STR) END PROGRAM
The C procedure:
#include <stdio.h> void GUREC(int *ldr, char *daterec, int *iil, int *irl, int *errind, int *il, int *ia, int *rl, int *ra, int *sl, int *lstr, char *str){ char *p=str; printf("ldr = %d, iil = %d, irl = %d, errind=%d, STR(3)=str[2]='%s'\n", *ldr, *iil, *irl, *errind, p+2*17); }
Note the uppercase name of the C procedure, the explicit null-termination of the string in the caller, and the explicit address calculation for the substring/string-array element in the callee. Any of these matters can give you trouble, and you have to decide whether you want such a quick-and-dirty solution or you should invest in a portable solution based on the Fortran-C Interoperability facilities.

- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page