By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
445,857 Members | 1,760 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 445,857 IT Pros & Developers. It's quick & easy.

C code to replace Fortran library

P: n/a
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
Share this Question
Share on Google+
5 Replies


P: n/a
"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

P: n/a
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

P: n/a
"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

P: n/a
"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

P: n/a
"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 discussion thread is closed

Replies have been disabled for this discussion.