473,323 Members | 1,550 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,323 software developers and data experts.

C strings to Fortran

Ok, I know this is a common topic, but I didn't find any post that
solves my current problem. I'm using Microsoft Visual C++ 6.0 (SP5),
and Intel Fortran 7.1 Compiler for Windows.

I'm trying to pass a C character string to my Fortran code.
Here is the code (a very simple one):

********** C print.c listing **********
#include <stdio.h>

extern "C" {
void __stdcall PRINT_STRING(char *);
}

int main(void)
{
char *cstring = "Hello World!";
PRINT_STRING(cstring);
return 0;
}
********** Fortran print.f listing **********
subroutine PRINT_STRING(fstring)
CHARACTER*30 fstring
print *,'Fortran string: ',fstring
end
*********************************************

The output is wrong, and I got something like:
" Fortran string: $"
(the '$' may change for any other ascii character)

So, I've tried the hidden-length method, but the linker doesn't like
it:
"test.obj : error LNK2001: unresolved external symbol _PRINT_STRING@8
Debug/test.exe : fatal error LNK1120: 1 unresolved externals"
(I only declare the length parameter into the C listing as written in
some posts here).

If someone got an idea on how to pass those strings, or got a miracle
lib/function to convert those C strings (remember, I use Intel Fortran
Compiler and there is nothing into the documentation that may help
about it...).

I can't neither use CHARACTER*(*) since the Fortran compiler is
complaining about "Error 531 : The variable CSTRING cannot be a value
dummy argument use CHARACTER(*) instead." (even if I use CHARACTER(*)
as written...).

Hey, dudes, help me!
Thanx a lot

Thanks!
Nov 13 '05 #1
11 8599
ac****@netcourrier.com (John Smith) wrote:
# Ok, I know this is a common topic, but I didn't find any post that
# solves my current problem. I'm using Microsoft Visual C++ 6.0 (SP5),
# and Intel Fortran 7.1 Compiler for Windows.

That should be detailed in the "Calling Conventions" of the compiler
documentation. If you don't already have the compiler reference guide,
you can try poking around
http://support.intel.com/support/per...ows/manual.htm
or
http://www.intel.com/software/produc...cs/for_prg.htm
for a downloadable copy. Every compiler documentation I have ever seen
has such a section.

--
Derk Gwen http://derkgwen.250free.com/html/index.html
I think that's kinda of personal; I don't think I should answer that.
Nov 13 '05 #2
On 5 Aug 2003 16:37:01 -0700, ac****@netcourrier.com (John Smith) wrote:
Ok, I know this is a common topic, but I didn't find any post that
solves my current problem. I'm using Microsoft Visual C++ 6.0 (SP5),
and Intel Fortran 7.1 Compiler for Windows.

I'm trying to pass a C character string to my Fortran code.
Here is the code (a very simple one):

********** C print.c listing **********
#include <stdio.h>

extern "C" {
void __stdcall PRINT_STRING(char *);
}

int main(void)
{
char *cstring = "Hello World!";
PRINT_STRING(cstring);
return 0;


Replace the above with:

#include <stdio.h>

extern "C" {
void l PRINT_STRING(char *, int slen);
}

int main(void)
{
char *cstring = "Hello World!";
PRINT_STRING(cstring, strlen(cstring));
return 0;

The two changes are:

1: Remove __stdcall - Intel Fortran doesn't use the STDCALL convention by
default.
2. Add the hidden length argument. The hidden length is an int passed by
value after all the arguments.

Note that both of these items are different conventions than Compaq Visual
Fortran uses - CVF does use STDCALL and puts length arguments immediately
after the address. In this example, the latter doesn't matter, but it would
if you passed more than one actual argument.

A good resource for questions such as this is the Intel Fortran/Compaq Visual
Fortran user forum at http://intel.com/IDS/forums/fortran - I invite you to
join the growing and active community there.
Compaq Visual Fortran Support: http://compaq.com/fortran/support/visual.html
Intel Fortran Support: http://developer.intel.com/software/products/support/
Steve Lionel
Software Products Division
Intel Corporation
Nashua, NH

User communities for Intel Fortran and Compaq Visual Fortran:
http://intel.com/IDS/forums/fortran
Nov 13 '05 #3
On 6 Aug 2003 15:11:01 GMT, Da*****@cern.ch (Dan Pop) wrote:
In <ql********************************@4ax.com> Steve Lionel <St**********@intel.com> writes:
extern "C" {
void l PRINT_STRING(char *, int slen);
}


I'm afraid that no conforming C compiler can silently accept this
gibberish. The first and last line must be conditionally removed when
the code is compiled by a C compiler (the classical #ifdef __cplusplus
stuff) and the l in the function declaration simply makes no sense.


Sorry - the spurious "I" after "void" was a typo and should be removed. You
are also correct that if the file is named with a .c file type, the "C" from
the extern declaration should be removed. If it is .cpp instead, then it is
correct as stated, or one can use the #ifdef as you suggest.

Compaq Visual Fortran Support: http://compaq.com/fortran/support/visual.html
Intel Fortran Support: http://developer.intel.com/software/products/support/
Steve Lionel
Software Products Division
Intel Corporation
Nashua, NH

User communities for Intel Fortran and Compaq Visual Fortran:
http://intel.com/IDS/forums/fortran
Nov 13 '05 #4
John Smith wrote:
Ok, I know this is a common topic, but I didn't find any post that
solves my current problem. I'm using Microsoft Visual C++ 6.0 (SP5),
and Intel Fortran 7.1 Compiler for Windows.

I'm trying to pass a C character string to my Fortran code.
Here is the code (a very simple one):

/********** C print.c listing **********/
#include <cstdio>
#include <cstring>
extern "C" {
void print_string_(const char *, int);
}

int main(int argc, char* argv[]) {
const
char *cstring = "Hello World!";
print_string_(cstring, strlen(cstring));
return 0;
}
c********** Fortran print.f listing **********
subroutine PRINT_STRING(fstring)
CHARACTER(*) fstring
print *,'Fortran string: ',fstring
end
c*********************************************


Nov 13 '05 #5
"Greg Chien" <gc****@n.o.S.p.a.m.protodesign-inc.com> writes:

[about the "hidden" string length argument in many current compilers]
2. Does F2KV address this issue in C-interop?


Yes. F2k (or whatever I have to now call it...apparently F2003,
though that wasn't my choice) addresses this.

The "hidden" arguments are ways of providing information needed to
make assumed-length character dummy arguments work in f77. Because
f77 had no concept of explicit interfaces, the information pretty
much had to be passed for all character arguments. F90/F95/F2whatever
all inherit this for compatibility.

However, it is fundamental to the C interop feature in f2whatever that
the compiler has to know when it is dealing with an interoperable
procedure. This is done by having an explicit interface with the
BIND(C) attribute. If the compiler sees that attribute, it will know
to use an interface appropriate to the C compiler. The low-level
details are technically up to the processor, but in practice none of
the C compilers are likely to have anything like such a hidden
argument, so the compiler won't generate one. In any case,
the implementation has to be compatible with C code that looks
like the specified interface - if there is something "hidden",
then it must be equally hidden from the C code perspective.

Of course, if you want to pass the string length explicitly (as
might be a useful thing to do), then you can do so. But in that
case, there is nothing hidden or otherwise special about it; it
goes wherever you explicitly put it.

--
Richard Maine | Good judgment comes from experience;
email: my first.last at org.domain | experience comes from bad judgment.
org: nasa, domain: gov | -- Mark Twain
Nov 13 '05 #6
Thank you all for your answers.

I've removed the __stdcall statement and put hidden arguments. It
linked but didn't work much.

So I tried to use the "CHARACTER*(*)" statement, and, by renaming my
..for file to .f90, and surprisingly it simply worked :)
But I got another problem right now :)
I have a global C variable (which we will call "foo").
I want to retrieve it into my Fortran Subroutine BAR() without passing
it as an argument.

So I tried to use a COMMON block (my variable is declared in the C
source file as "int foo"). I declared a "COMMON foo" inside the
fortran code, but it doesn't seem to work. I've read that I may use
struct to resolve this but I can't manage to do it :(

Could you help me anymore ?
Nov 13 '05 #7
# So I tried to use a COMMON block (my variable is declared in the C
# source file as "int foo"). I declared a "COMMON foo" inside the
# fortran code, but it doesn't seem to work. I've read that I may use
# struct to resolve this but I can't manage to do it :(

You need to verify this against the documentation, but usually it would be

COMMON /foo/ foo
INTEGER foo

The idea being each C global variable (of whatever type) becomes one
Fortran labelled common block whose variables match C type. However
there is often some name mangling with added or deleted underscores
between C and Fortran external symbols.

--
Derk Gwen http://derkgwen.250free.com/html/index.html
JUSTICE!
Justice is dead.
Nov 13 '05 #8
On Wed, 06 Aug 2003 20:28:29 GMT, "Greg Chien"
<gc****@n.o.S.p.a.m.protodesign-inc.com> wrote:
1. Do IFC and the future IVF support "after string arg"? Which is the
default?


IFC defaults to "after all args". There is a /Gm switch which provides
compatibility with CVF (and Microsoft Forttran PowerStation) - this changes
the calling mechanism to STDCALL and the string length passing to "after
string". There is no way to separate these.

Intel Visual Fortran will use the same default as IFC, which differs from CVF.
There will be options to get the CVF conventions (with more flexibility.)


Compaq Visual Fortran Support: http://compaq.com/fortran/support/visual.html
Intel Fortran Support: http://developer.intel.com/software/products/support/
Steve Lionel
Software Products Division
Intel Corporation
Nashua, NH

User communities for Intel Fortran and Compaq Visual Fortran:
http://intel.com/IDS/forums/fortran
Nov 13 '05 #9
"Steve Lionel" wrote
IFC defaults to "after all args". There is a /Gm switch which
provides compatibility with CVF (and Microsoft Forttran
PowerStation) - this changes the calling mechanism to
STDCALL and the string length passing to "after
string". There is no way to separate these.
Would be nicer if the user can have finer control.
Intel Visual Fortran will use the same default as IFC, which
differs from CVF. There will be options to get the CVF
conventions (with more flexibility.)


Sounds better :-) Thanks for the explanations.

--
Best Regards,
Greg Chien
e-mail: remove n.o.S.p.a.m.
http://protodesign-inc.com
Nov 13 '05 #10
"Greg Chien" <gc****@n.o.S.p.a.m.protodesign-inc.com> writes:
Thanks, Richard. I had to re-read J3/03-007.pdf and I think it is
worthwhile to point out Section 15.2.6, especially the example in NOTE
15.23, for people who would like further reading.
Thanks. (I wrote at least the first draft of that note because I
thought it really needed explaining.)
Am I safe to say that a F200x conforming compiler shall not
expect/generate hidden lengths of strings in the arguments internally when
BIND(C) is specified in a procedure?
Yes. Notice also that you won't be able to have assumed-length
dummies in such a procedure (because they wouldn't work, so the
standard prohibits them in that case).
Well, at least in a practical sense.
I don't think a Fortran compiler writer knows which C compiler their
customers will use,
Mostly it won't matter except in cases where there are C compilers for
the same platform but having interface incompatibilities. I'm told
that some such cases exist and that the vendors will most likely
have compiler switches to indicate which set of C conventions you
need to interoperate with.
nor do I know of any C compiler that produces hidden
length arguments to satisfy Fortran needs.
Me neither.
If the above is true, it is actually a good news to me because the
(implicit) positions of these hidden length arguments always cause
confusions on the C side....


Yes. That's sort of the point of the standard - to facilitate
portability. You can do most of this stuff (C interop) today,
but you have to do different things with different compilers.
Plus, today you sometimes have to be able to write enough C to
write "wrapper" code in C; with the C interop in f2003, it is
hoped that there will be less need to write such C wrappers;
you can tell your Fortran code how to call the C.

--
Richard Maine | Good judgment comes from experience;
email: my first.last at org.domain | experience comes from bad judgment.
org: nasa, domain: gov | -- Mark Twain
Nov 13 '05 #11
"Richard Maine" wrote
"Greg Chien" writes:
Am I safe to say that a F200x conforming compiler shall not
expect/generate hidden lengths of strings in the arguments
internally when BIND(C) is specified in a procedure?
Yes. Notice also that you won't be able to have assumed-length
dummies in such a procedure (because they wouldn't work, so the
standard prohibits them in that case).


I think it is fair to have such limit, given the complexity from each
language.
Yes. That's sort of the point of the standard - to facilitate
portability. You can do most of this stuff (C interop) today,
but you have to do different things with different compilers.
Plus, today you sometimes have to be able to write enough C to
write "wrapper" code in C; with the C interop in f2003, it is
hoped that there will be less need to write such C wrappers;
you can tell your Fortran code how to call the C.


.... and vice versa, which is mostly what we do.

It is good to have someone (like you) to interpret the standard/draft in
c.l.f. It's hard to notice the hidden string length issue by a glimpse
through 15.2.6.

--
Best Regards,
Greg Chien
e-mail: remove n.o.S.p.a.m.
http://protodesign-inc.com
Nov 13 '05 #12

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

44
by: Carl | last post by:
"Nine Language Performance Round-up: Benchmarking Math & File I/O" http://www.osnews.com/story.php?news_id=5602 I think this is an unfair comparison! I wouldn't dream of developing a numerical...
15
by: Nick Coghlan | last post by:
Thought some folks here might find this one interesting. No great revelations, just a fairly sensible piece on writing readable code :) The whole article:...
5
by: NM | last post by:
Hi all I am trying to link C++ and Fortran.I am not very familiar with Fortran. I have been successful in linking C++ and fortran using g++ and ifc for simple program. So adding _ to at the end of...
4
by: NM | last post by:
Hello All I am writing some progam that involves both C++ and Fortran. Some of the existing code is in Fortran. The main program will be in C++ and it will call some Fortran subroutine. All the...
6
by: Adrian | last post by:
I am trying to pass the address of a C++ function into a Fortran routine to enable the Fortran routine to call this C++ function. I have to do it this way as our build process does not allow...
1
by: Sam | last post by:
Hello all I have a two dimensional array (the dimensions are not known) that needs to be passed to fortran from c++, allocate the dimensions of the array in fortran code, do some filling up of...
2
by: NM | last post by:
Hello all, I am supposed to do some mixed programming with c++ and fortran. I was succeeful in exchanging the 2D arrays from fortran to c++ and the other way, but was unable to that same with...
81
by: Matt | last post by:
I have 2 questions: 1. strlen returns an unsigned (size_t) quantity. Why is an unsigned value more approprate than a signed value? Why is unsighned value less appropriate? 2. Would there...
9
by: travisperkins03 | last post by:
Hi, I have read somewhere that C code sometimes cannot be compiled to be as efficient as FORTRAN, eg for matrix multiplication, because a C compiler cannot make the assumptions about arrays that...
0
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
0
by: Vimpel783 | last post by:
Hello! Guys, I found this code on the Internet, but I need to modify it a little. It works well, the problem is this: Data is sent from only one cell, in this case B5, but it is necessary that data...
0
by: jfyes | last post by:
As a hardware engineer, after seeing that CEIWEI recently released a new tool for Modbus RTU Over TCP/UDP filtering and monitoring, I actively went to its official website to take a look. It turned...
0
by: ArrayDB | last post by:
The error message I've encountered is; ERROR:root:Error generating model response: exception: access violation writing 0x0000000000005140, which seems to be indicative of an access violation...
1
by: PapaRatzi | last post by:
Hello, I am teaching myself MS Access forms design and Visual Basic. I've created a table to capture a list of Top 30 singles and forms to capture new entries. The final step is a form (unbound)...
1
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
1
by: Defcon1945 | last post by:
I'm trying to learn Python using Pycharm but import shutil doesn't work
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome former...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.