473,508 Members | 2,040 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

C code to replace Fortran library

Hello,

I am unaware whether this is the right group to ask. Please point me
to another forum if required.

I would like to replace a Fortran function by one which is written in
C. The function shall provide the same interface for the fortran code
calling the library. Fortunately, this works - currently under WinNT -
well for all functions which do not return a string, e.g.

CHARACTER*16 MYSTRFUNC()

Unfortunately, the MSDN help does not explain how to implement this
kind of function. Also the web was not of help.

Did I oversee something? Could anybody point me to some suitable
information or even provide me with sample code?

Regards, Michael
Nov 13 '05 #1
5 2702
"Michael Hiegemann" <mi***************@power.alstom.com> wrote:
I would like to replace a Fortran function by one which is
written in C. The function shall provide the same interface
for the fortran code calling the library. Fortunately, this
works - currently under WinNT - well for all functions which
do not return a string, e.g.

CHARACTER*16 MYSTRFUNC()


Unfortunately, the obvious solution:
char mystrfunc()[16];
which is read as "declare mystrfunc as function returning array
16 of char" is not allowed in C. You can't return an array from
a function.

If you are talking binary compatibility with the Fortran code then
you will need to look into how this array return functionality is
implemented in your Fortran compiler. That is off-topic here.

In general C code there are at least four possible workarounds,
presented in order from best to worst practise in C code:

#include <stdlib.h>
#include <string.h>

/* Caller supplies array to fill in */
void mystrfunc1(char *dest)
{
strcpy(dest, "output");
}

/* Caller must free the allocated memory */
char *mystrfunc2(void)
{
char *p = malloc(16);
if(p) strcpy(p, "output");
return p;
}

/* Caller receives a pointer to a string literal which
is static and unmodifyable */
const char *mystrfunc3(void)
{
return "output";
}

/* Caller receives a pointer to a static array, which is
overwritten if the function is called again. This is
not safe for recursion, reentrancy or multithreading */
char *mystrfunc4(void)
{
static char result[16];
strcpy(result, "output");
return result;
}

What you MUST NOT do is return a pointer to an automatic object:
char *mystrfunc5(void)
{
char result[16];
strcpy(result, "output");
return result;
}
Because the result array is deallocated when the function returns
you return an invalid pointer, and the memory may be reused before
the caller grabs the results.

--
Simon.
Nov 13 '05 #2
Simon Biber wrote:
"Michael Hiegemann" <mi***************@power.alstom.com> wrote:
I would like to replace a Fortran function by one which is
written in C. The function shall provide the same interface
for the fortran code calling the library. Fortunately, this
works - currently under WinNT - well for all functions which
do not return a string, e.g.

CHARACTER*16 MYSTRFUNC()

.... snip ...
If you are talking binary compatibility with the Fortran code then
you will need to look into how this array return functionality is
implemented in your Fortran compiler. That is off-topic here.

In general C code there are at least four possible workarounds,
presented in order from best to worst practise in C code:


You omitted defining a structure with the sole content being an
array of char. This can be passed and returned by value.

struct fortranstring16 {
char data[16];
}

--
Replies should be to the newsgroup
Replace this line to publish your e-mail address.
Nov 13 '05 #3
"LibraryUser" <de**********@made.invalid> wrote:
You omitted defining a structure with the sole content
being an array of char. This can be passed and returned
by value.

struct fortranstring16 {
char data[16];
}


Yes, that is probably closer semantically to the Fortran
code. I didn't think of it because it's not something I
would ever do in C code.

Returning structures by value can be implemented in many
different ways, and may not be binary compatible with the
Fortran compiler on the OP's system.

--
Simon.
Nov 13 '05 #4
"Simon Biber" <sb****@optushome.com.au> wrote in message news:<3f**********************@news.optusnet.com.a u>...
"Michael Hiegemann" <mi***************@power.alstom.com> wrote:
I would like to replace a Fortran function by one which is
written in C. The function shall provide the same interface
for the fortran code calling the library. Fortunately, this
works - currently under WinNT - well for all functions which
do not return a string, e.g.

CHARACTER*16 MYSTRFUNC()


Unfortunately, the obvious solution:
char mystrfunc()[16];
which is read as "declare mystrfunc as function returning array
16 of char" is not allowed in C. You can't return an array from
a function.

If you are talking binary compatibility with the Fortran code then
you will need to look into how this array return functionality is
implemented in your Fortran compiler. That is off-topic here.

In general C code there are at least four possible workarounds,
presented in order from best to worst practise in C code:

#include <stdlib.h>
#include <string.h>

/* Caller supplies array to fill in */
void mystrfunc1(char *dest)
{
strcpy(dest, "output");
}

/* Caller must free the allocated memory */
char *mystrfunc2(void)
{
char *p = malloc(16);
if(p) strcpy(p, "output");
return p;
}

/* Caller receives a pointer to a string literal which
is static and unmodifyable */
const char *mystrfunc3(void)
{
return "output";
}

/* Caller receives a pointer to a static array, which is
overwritten if the function is called again. This is
not safe for recursion, reentrancy or multithreading */
char *mystrfunc4(void)
{
static char result[16];
strcpy(result, "output");
return result;
}

What you MUST NOT do is return a pointer to an automatic object:
char *mystrfunc5(void)
{
char result[16];
strcpy(result, "output");
return result;
}
Because the result array is deallocated when the function returns
you return an invalid pointer, and the memory may be reused before
the caller grabs the results.


Simon,

thanks a lot for the analysis. My problem seems to be close to your
case

/* Caller receives a pointer to a string literal which
is static and unmodifyable */
const char *mystrfunc3(void)
{
return "output";
}

After a lot of experiments I found that it is generally a good idea to
define a FortranString struct type to be used in the function's
argument list as it saves a lot of writing and is good for overview.
For the sake of completeness I provide my results of the weekend as it
might be a good starting point for others:

For the Microsoft implementation of the Fortran string I got

struct fortran_string
{
char * String; /* Pointer to the first character */
unsigned long Length; /* Number of characters allocated at
compile time */
};
typedef struct fortran_string FortranString;

This is the way they insure that the string length is always. The
actual string length is a backward iteration looking for the first
non-white space character, to be distinguished from the number of
characters allocated at compile time. This can be used for any void
function argument as well and keeps the number of arguments in the C
implementation equal to the number of arguments visible in Fortran.

The C implementation of a Fortran function returning string is a void
function with the very first argument representing the return string:

void
MYSTRFUNC(FortranString fstring /* your arguments go here */)
{
static const char mystring[] = "Sixteen";
int length;

/* Trailing blanks required */
memset(fstring.String, ' ', fstring.Length);

/* Avoid array bounds violation */
length = min(fstring.Length, strlen(mystring));

memcpy(fstring.String, mystring, length);
}

Thanks a lot, also to all other contributors.

Michael
Nov 13 '05 #5
"Simon Biber" <sb****@optushome.com.au> wrote in message news:<3f**********************@news.optusnet.com.a u>...
"Michael Hiegemann" <mi***************@power.alstom.com> wrote:
I would like to replace a Fortran function by one which is
written in C. The function shall provide the same interface
for the fortran code calling the library. Fortunately, this
works - currently under WinNT - well for all functions which
do not return a string, e.g.

CHARACTER*16 MYSTRFUNC()


Unfortunately, the obvious solution:
char mystrfunc()[16];
which is read as "declare mystrfunc as function returning array
16 of char" is not allowed in C. You can't return an array from
a function.

If you are talking binary compatibility with the Fortran code then
you will need to look into how this array return functionality is
implemented in your Fortran compiler. That is off-topic here.

In general C code there are at least four possible workarounds,
presented in order from best to worst practise in C code:

#include <stdlib.h>
#include <string.h>

/* Caller supplies array to fill in */
void mystrfunc1(char *dest)
{
strcpy(dest, "output");
}

/* Caller must free the allocated memory */
char *mystrfunc2(void)
{
char *p = malloc(16);
if(p) strcpy(p, "output");
return p;
}

/* Caller receives a pointer to a string literal which
is static and unmodifyable */
const char *mystrfunc3(void)
{
return "output";
}

/* Caller receives a pointer to a static array, which is
overwritten if the function is called again. This is
not safe for recursion, reentrancy or multithreading */
char *mystrfunc4(void)
{
static char result[16];
strcpy(result, "output");
return result;
}

What you MUST NOT do is return a pointer to an automatic object:
char *mystrfunc5(void)
{
char result[16];
strcpy(result, "output");
return result;
}
Because the result array is deallocated when the function returns
you return an invalid pointer, and the memory may be reused before
the caller grabs the results.


Simon,

thanks a lot for the analysis. My problem seems to be close to your
case

/* Caller receives a pointer to a string literal which
is static and unmodifyable */
const char *mystrfunc3(void)
{
return "output";
}

After a lot of experiments I found that it is generally a good idea to
define a FortranString struct type to be used in the function's
argument list as it saves a lot of writing and is good for overview.
For the sake of completeness I provide my results of the weekend as it
might be a good starting point for others:

For the Microsoft implementation of the Fortran string I got

struct fortran_string
{
char * String; /* Pointer to the first character */
unsigned long Length; /* Number of characters allocated at
compile time */
};
typedef struct fortran_string FortranString;

This is the way they insure that the string length is always. The
actual string length is a backward iteration looking for the first
non-white space character, to be distinguished from the number of
characters allocated at compile time. This can be used for any void
function argument as well and keeps the number of arguments in the C
implementation equal to the number of arguments visible in Fortran.

The C implementation of a Fortran function returning string is a void
function with the very first argument representing the return string:

void
MYSTRFUNC(FortranString fstring /* your arguments go here */)
{
static const char mystring[] = "Sixteen";
int length;

/* Trailing blanks required */
memset(fstring.String, ' ', fstring.Length);

/* Avoid array bounds violation */
length = min(fstring.Length, strlen(mystring));

memcpy(fstring.String, mystring, length);
}

Thanks a lot, also to all other contributors.

Michael
Nov 13 '05 #6

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

Similar topics

7
5195
by: Anonymous | last post by:
I have a mixed-language pgm (Fortran and C++) which needs to pass a few hundred values from C++ to Fortran. One way to do this is to have a Fortran module and a C++ structure (or class) with an...
20
2978
by: maria | last post by:
I 've decided it's time to move from fortran to c++, but i cant find out if c++ supposrts I/O format commands like the ones in fortran 77. I would be gratefull for any help. Thank you
13
2498
by: NM | last post by:
Sometimes ago I was having a problem in linking between C++ and Fortran program. That was solved (using input from this newsgroup) using the Fortran keyword "sequence" with the derived types (to...
22
2836
by: Michael Nahas | last post by:
Antti & all interested, The draft description of my language to replace C is available at: http://nahas.is-a-geek.com/~mike/MyC.pdf I am a long time C programmer (I read the old testament...
10
2653
by: Julian | last post by:
I get the following error when i try to link a fortran library to a c++ code in .NET 2005. LINK : fatal error LNK1104: cannot open file 'libc.lib' the code was working fine when built using...
11
2948
by: Cottonwood | last post by:
I want to call a GNU-Fortran-library from a GNU-C++ source. Is that possible at all? If yes, what is to be done to link the program? I get an error message that says that the module MAIN_ cannot...
21
2731
by: Cottonwood | last post by:
I want to call a C module from a Fortran program. Whatever I tried - the linker could not find the C module. I know about the leading underscore and switched even that off. I abstracted everything...
11
1917
by: Eigenvector | last post by:
I apologize if this is a trivial question, but it's always made me wonder when I have to compile my code. There are some #includes that you don't really need to reference in your library and...
3
5159
by: unexpected | last post by:
Hi all, I'm currently working on a large, legacy Fortran application. I would like to start new development in Python (as it is mainly I/O related). In order to do so, however, the whole project...
0
7226
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
7125
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...
0
7328
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,...
0
5631
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
1
5055
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...
0
4709
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...
0
3199
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...
1
767
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
0
422
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...

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.