forums.silverfrost.com Forum Index forums.silverfrost.com
Welcome to the Silverfrost forums
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Passing UNICODE strings from FTN95 to C++
Goto page 1, 2  Next
 
Post new topic   Reply to topic    forums.silverfrost.com Forum Index -> Support
View previous topic :: View next topic  
Author Message
Anonymous
Guest





PostPosted: Fri Sep 09, 2005 5:58 am    Post subject: Passing UNICODE strings from FTN95 to C++ Reply with quote

Sirs,

I have a question about passing UNICODE strings from Fortran to C using FTN95.

I am familiar with the concept of declaring C functions using the STDCALL declaration and defining string arguments using the INSTRING macro – eg.

STDCALL REGTITLESTRING 'RegTitleString' (INSTRING(256))

The C function then nicely receives a C string with terminating NULL character – which works fine.

I am now trying to cater for UNICODE (double byte) character strings in my Fortran by reading them in from a resource or data file and storing them in normal Fortran character variables. These are read in using the normal READ command and are stored (with trailing blanks) in the normal way.

I have a problem using the INSTRING macro in these circumstances, as it appears that the macro truncates the string prematurely if it contains a NULL character within, which is quite likely in UNICODE.

As I am in control of the string passing in other compilers, where the string length is passed, I can strip off trailing blanks and add a double NULL at the end and the new string can be treated as a UNICODE string in the C code (when compiled using #define UNICODE).

Can you suggest a similar mechanism when using FTN95?

Thanking you in anticipation.

David Bradly
Product Development Manager
Bradly Associates Ltd Tel: +44 (116) 254 0697
"Whiteknights" E-mail : support@gino-graphics.com
Finchampstead URL : http://www.gino-graphics.com/
Berkshire
U.K. RG40 3SY
Back to top
PaulLaidler
Site Admin


Joined: 21 Feb 2005
Posts: 7924
Location: Salford, UK

PostPosted: Fri Sep 09, 2005 6:59 am    Post subject: Passing UNICODE strings from FTN95 to C++ Reply with quote

You might try passing the string as a REF rather than an INSTRING.

The longer way would be to replace single NULLs by something else before passing the string
and then convert back again at the other end.
Back to top
View user's profile Send private message AIM Address
Anonymous
Guest





PostPosted: Fri Sep 09, 2005 7:55 am    Post subject: Passing UNICODE strings from FTN95 to C++ Reply with quote

Paul,

If you pass the string through as a REF, does a length get passed in any way, by value or by reference?

David
Back to top
PaulLaidler
Site Admin


Joined: 21 Feb 2005
Posts: 7924
Location: Salford, UK

PostPosted: Sun Sep 11, 2005 2:16 am    Post subject: Passing UNICODE strings from FTN95 to C++ Reply with quote

If you export a Fortran CHARACTER variable then hidden length values will be added to the end of the argument list (one for each CHARACTER argument). Note that this is different in CVF etc were the hidden length comes immediately after the argument.

The alternative is to export an INTEGER*1 array (or even better, an INTEGER*2 array). This will be a standard Fortran array.

Regards

Paul
Back to top
View user's profile Send private message AIM Address
Anonymous
Guest





PostPosted: Tue Sep 13, 2005 10:43 am    Post subject: Passing UNICODE strings from FTN95 to C++ Reply with quote

Paul,

I have tried to pick up a string length (when defining a Fortran string as REF), but without success. Can you tell me where I am going wrong.

F90 code ----
!STDCALL REGTEXT 'RegText' (INSTRING(256))
STDCALL REGTEXT 'RegText' (REF)
character*12 text
text='ab defghijkl'
text(3:3)=char(0)
call regtext(text)
stop
end

C++ Code ---
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define min(a,b) (((a) < (b)) ? (a) : (b))
#define max(a,b) (((a) > (b)) ? (a) : (b))
#define STRNCPY1(y,x,l) {int ic,il; for (il=l-1; x[il] == ' ' && il >= 0; il--) { } for (ic = 0; ic <= il; ic++) { y[ic] = x[ic]; } y[il+1] = ''; y[il+2] = ''; }

extern "C" { void __stdcall
#ifdef INSTRING
RegText(char *title)
{
int len=strlen(title);
#else
RegText(char *s, int len)
{
char title[256];

STRNCPY1(title, s, min(254,len));
#endif

printf("String = %s %dn",title,len);

}
}


Basically I am trying to pass all 12 characters through to the C code as if it was a UNICODE string
Back to top
PaulLaidler
Site Admin


Joined: 21 Feb 2005
Posts: 7924
Location: Salford, UK

PostPosted: Wed Sep 14, 2005 1:38 am    Post subject: Passing UNICODE strings from FTN95 to C++ Reply with quote

Here is a simple example that uses C_EXTERNAL.
If you need to use STDCALL then I will have to think again.

!Fortran main program...
C_EXTERNAL REGTEXT 'RegText'(INSTRING)
call regtext("Hello World")
end


//C library....
#include <stdio.h>
extern "C" void RegText(char* t, int len)
{
printf(%sn", t);
}

Linking...

SLINK
lo main
lo lib
file
Back to top
View user's profile Send private message AIM Address
Anonymous
Guest





PostPosted: Wed Sep 14, 2005 8:23 am    Post subject: Passing UNICODE strings from FTN95 to C++ Reply with quote

Paul,

There is a basic problem with the code you sent. The value of 'len' in the C code is meaningless. Try this:

//C library....
#include <stdio.h>
extern "C" void RegText(char* t, int len)
{
printf("%s %dn", t,len);
}

Len comes out at 12267 on my machine.

The point is I am trying to pass a UNICODE string to the C which may contain NULL's, so I need the actual length - unless 12267 can be interpreted in some way.

Can you help please.
Back to top
PaulLaidler
Site Admin


Joined: 21 Feb 2005
Posts: 7924
Location: Salford, UK

PostPosted: Mon Sep 19, 2005 4:28 am    Post subject: Passing UNICODE strings from FTN95 to C++ Reply with quote

Sorry. Here is the corrected code....

!Fortran main program
C_EXTERNAL REGTEXT 'RegText'(INSTRING)
CHARACTER*30 msg
msg = "Hello World"C
call regtext(msg)
msg = "This is a message"//char(0)
call regtext(msg)
msg(5:5) = char(0)
call regtext(msg)
end

//C library
#include <stdio.h>
#include <string.h>
extern "C" void RegText(char* t)
{
printf("%dn", strlen(t));
printf("%sn", t);
}

Back to top
View user's profile Send private message AIM Address
Anonymous
Guest





PostPosted: Mon Sep 19, 2005 5:04 am    Post subject: Passing UNICODE strings from FTN95 to C++ Reply with quote

Thanks Paul, but how do I get the full length of the string?

The point about UNICODE strings is that they contain NULL's in them and I need the full length of the string passed from Fortran not just the characters preceeding the first NULL.

Strictly speaking I need a length of 30 in both cases as this is the length of the Fortran String. I understand that this is the value passed in other compilers with the hidden length argument.
Back to top
PaulLaidler
Site Admin


Joined: 21 Feb 2005
Posts: 7924
Location: Salford, UK

PostPosted: Mon Sep 19, 2005 9:37 am    Post subject: Passing UNICODE strings from FTN95 to C++ Reply with quote

Here is another way....

!Fortran main program
C_EXTERNAL REGTEXT 'RegText'(INSTRING,VAL)
CHARACTER*30 msg
msg = "Hello World"C
call regtext(msg,LEN(msg))
msg = "This is a message"//char(0)
call regtext(msg,LEN((msg))
msg(5:5) = char(0)
call regtext(msg,LEN(msg))
end

//C library
#include <stdio.h>
#include <string.h>
extern "C" void RegText(char* t, int len)
{
printf("%dn", len);
printf("%sn", t);
}
Back to top
View user's profile Send private message AIM Address
Anonymous
Guest





PostPosted: Tue Sep 20, 2005 10:50 am    Post subject: Passing UNICODE strings from FTN95 to C++ Reply with quote

Paul,

I agree that this does work, but it means that I have to change all my calls to C functions to add the additional argument onto the end, whereas with all the other compilers this length is passed automatically.

Is there any chance I could request that the INSTRING macro is changed so that it passes the whole string across and simply adds a NULL onto the end of the complete string - even if there is one in the middle somewhere? In normal circumstances (ie. non UNICODE) the NULL terminated string will be dealt with as per usual, but I will add another NULL on to the end to make it a properly terminated UNICODE string.

Can I ask if anyone else is trying to use UNICODE strings in a mixed FTN95/C environment and if so, how are they achieveing success?

I look forward to hearing from you.

Back to top
PaulLaidler
Site Admin


Joined: 21 Feb 2005
Posts: 7924
Location: Salford, UK

PostPosted: Wed Sep 21, 2005 12:48 am    Post subject: Passing UNICODE strings from FTN95 to C++ Reply with quote

If you are willing to use only upper case letters in the C code then you could do the following....

//Fortran...
character*30 str
str = "Hello World"C
call regtext(st)
end

//C code....
#include <stdio.h>
extern "C" void REGTEXT(char* t, int len)
{
printf("%dn",len);
printf("%sn",t);
}
Back to top
View user's profile Send private message AIM Address
Anonymous
Guest





PostPosted: Thu Sep 22, 2005 4:48 am    Post subject: Passing UNICODE strings from FTN95 to C++ Reply with quote

Paul,

That seems to provide what I am after. Thanks. It just means I have to change the C interface for FTN95 which is not so much of a big job. In fact it becomes the same as some other compilers, so I already have the code.

Now having done that on a test routine I have discovered another problem.

I am reading in a text file of UNICODE characters - i.e. an even number of bytes using Fortran Read ('a') format. Unfortunately where the UNICODE string include a SUB (26) character, FTN95 seems to skip over it and not put it in the string.

Can you suggest a switch or alternative method of reading in ALL bytes of a text file.

Thank you
Back to top
Andrew



Joined: 09 Sep 2004
Posts: 232
Location: Frankfurt, Germany

PostPosted: Thu Sep 22, 2005 3:29 pm    Post subject: Passing UNICODE strings from FTN95 to C++ Reply with quote

One way to ensure all data is being read from a file is to use the FTN95 specific routines OPENRW@, READF@ and READFA@. These make the code less portable, but you will be able to get raw data which you can then manipulate as you need to.
Back to top
View user's profile Send private message
Anonymous
Guest





PostPosted: Fri Sep 23, 2005 3:40 am    Post subject: Passing UNICODE strings from FTN95 to C++ Reply with quote

Andrew,

Thank you for the suggestion. Unfortunately neither routine is particularly suited to reading UNICODE text files containing the SUB (26) character.

Firstly READFA@ ignores them the same as READ and secondly READF@ does not read records (terminated with C/R (13)). As the strings of UNICODE characters are contained in variable length records (as any normal ASCII text file would do) it is quite difficult to use READF@ for this purpose.

Do you have any other suggestion for reading variable length records of UNICODE strings using FTN95?

Thanks
Back to top
Display posts from previous:   
Post new topic   Reply to topic    forums.silverfrost.com Forum Index -> Support All times are GMT + 1 Hour
Goto page 1, 2  Next
Page 1 of 2

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group