473,545 Members | 2,599 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

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(ch ar *);
}

int main(void)
{
char *cstring = "Hello World!";
PRINT_STRING(cs tring);
return 0;
}
********** Fortran print.f listing **********
subroutine PRINT_STRING(fs tring)
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 8618
ac****@netcourr ier.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****@netcourr ier.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(ch ar *);
}

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


Replace the above with:

#include <stdio.h>

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

int main(void)
{
char *cstring = "Hello World!";
PRINT_STRING(cs tring, 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**********@i ntel.com> writes:
extern "C" {
void l PRINT_STRING(ch ar *, 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_(c onst char *, int);
}

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


Nov 13 '05 #5
"Greg Chien" <gc****@n.o.S.p .a.m.protodesig n-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.protodesig n-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

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

Similar topics

44
3366
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 application in Python without using prebuilt numerical libraries and data objects such as dictionaries and lists. I have been experimenting with...
15
2078
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: http://www.acmqueue.com/modules.php?name=Content&pa=showpage&pid=271&page=1 The section specifically on white space:...
5
4009
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 fortran subroutine names when calling from C++ is working. Now I want to move to bigger program. I have a rather big Fortran code which compiles...
4
2847
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 memory allocation has to be done in C++. For arrays of structures and arrays (including multi-dimensional array) of primitive data types declared...
6
3514
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 circular dependencies of DLL's. Does anyone know how to do this, I have tried everything in my book. I have a C++ function GetP: DllExport void...
1
6398
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 the array in fortran and then accessing it in my c++ code. Say in my c++ code I have; extern "C" { void foo_(float **, int &, int &); }
2
3314
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 the 3D arrays, the values passed are not all the same. I am also pasting the fortran and c++ codes so that you could have a look at them. ////C++...
81
7234
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 be any advantage in having strcat and strcpy return a pointer to the "end" of the destination string rather than returning a
9
3811
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 a FORTRAN compiler can. But I don't understand the example, not least because I don't understand FORTRAN. I also don't understand why it is more...
0
7425
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language...
0
7682
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. ...
1
5351
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 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 a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes...
0
5069
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert...
0
3479
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in...
0
3465
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
1911
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
1
1037
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
0
734
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating...

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.