- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
!MS$ATTRIBUTES DLLEXPORT,STDCALL,ALIAS:'_Setcol@4'::SETCOL
INTEGER NEWCOL
CHARACTER(2) ARRAKY
write(*,*)' val '
write(*,*) NEWCOLLISION
write(*,*)' val '
ARRAKY= TRIM(ARRAKY)//CHAR(0)
write(*,*) ARRAKY
write(*,*)'aux '
END SUBROUTINE
val
3
val
aux
(two squares)
aux
2.- I am trying to store in a char what i am becoming from a native but i am getting the same behaviour.
SUBROUTINE SETMOL(NEWMOL)
!MS$ATTRIBUTES DLLEXPORT,STDCALL,ALIAS:'_Setmol@4'::SETMOL
CHARACTER(20) NEWMOL
CALL LVG('MEX',NEWMOL)
END SUBROUTINE
I do not know why in this case i am becoming the chian correctly but when i call the function only squares are sent
Many Thanks.
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
You need to look at "internal I/O"
eg :
character*60 :: a_string
integer :: a_number
write(a_string,*) a_number
In your case : WRITE(ARRAKY,*) NEWCOLLISION
Note : you may wish to use a specific format in place of the * whichputs a leading space at the beginning of the string
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Message Edited by patuco on 03-13-2006 10:11 AM
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
A little bit more explanation because i did not find the solution of both problems. Anyone can help me?:
1.-
SUBROUTINE SETCOL(NEWCOL)
!MS$ATTRIBUTES DLLEXPORT,STDCALL,ALIAS:'_Setcol@4'::SETCOL
INTEGER NEWCOL, aux
CHARACTER*16 :: ARRAKY
ARRAKY = ' '
WRITE(ARRAKY,*) NEWCOL
ARRAKY= TRIM(ARRAKY)//CHAR(0)
CALL COMLVG('SCOL',ARRAKY)
The fact is that the integer the subroutine receives is ok, the porblem is in the conversion, because some characters are being added, and i do not know how to avoid it.
2 in the second one I am trying to store in a char * in fortran what i am sending from a native written in C++ but the message sent is not what i supposed.
Here is what I am facing with:
int size = 20;
char * buf ;
printf("Calling the c function
");
buf = (char *)calloc(size,sizeof (char));
buf = (char *)env->GetStringUTFChars(prompt,NULL);
printf("String c1: %s
", buf);
printf(" Calling fortran
");
Setname(buf);
here the variable buf stores sorrectly what i am interested in
but in fortran i become something totally different ans strange.
the call to the native is as follows:
extern "C" void __stdcall Setname(const char *);
And the native:
SUBROUTINE SETNAME(NEWMOL)
!MS$ATTRIBUTES DLLEXPORT,STDCALL,ALIAS:'_Setname@4'::SETNAME
CHARACTER(20) NEWMOL
WRITE(*,*) "fortran "
WRITE(*,*) NEWMOL
WRITE(*,*) "end fortran "
CALL COMLVG('SET',NEWMOL)
END SUBROUTINE
I though it is something with c an the communication but i do not know where is the mistake. It can not be in fortran because it is not becoming correctly the string. If anyone could help me it would be great.
Many Thanks.
Message Edited by patuco on 03-14-2006 04:33 AM
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
OK First problem - though it may just be a typing mistake.
You have subroutine setcol with a dummy argument of NEWCOL, but later you are using NEWCOLLISON to write to arraky. What is NEWCOLLISION?
Les
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
!MS$ATTRIBUTES DLLEXPORT,STDCALL,ALIAS:'_Setcol@4'::SETCOL
INTEGER NEWCOL
CHARACTER(2) ARRAKY
write(*,*)' val '
write(*,*) NEWCOL
write(*,*)' val '
ARRAKY= TRIM(ARRAKY)//CHAR(0)
write(*,*) ARRAKY
write(*,*)'aux '
END SUBROUTINE
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
As far as I can see, Les Neilson has already pointed you to the correct form that you want.
When you program ARRAKY (a 2-character variable) = NEWCOL (an integer= 20, say for arguments sake) you will get the bit pattern representing the integer copied into ARRAKY, which willNOT be identical to the bit pattern that the character string '20' requires. You must use the internal write
WRITE(ARRAKY,'(i2')) NEWCOL
if you want the character string 'nn' to be stored in ARRAKY from integer 'nn' stored in NEWCOL.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thanks for the replies Les and Anthony.
The fact is that the subroutine is becoming the value but at the same time adding to it some trush. I do not know how to avoid or even eliminate it. I do not know how to trim in Fortran or if i have to force the chain with length.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
INTEGER NEWCOL CHARACTER*2 ARRAKY NEWCOL=2 ARRAKY=NEWCOL WRITE(*,*) "NEWCOL= ", NEWCOL WRITE(*,*) "ARRAKY= ", ARRAKYThe compiler, quite rightly, objects, telling meC:F90DFCODEVintegercharacterintegercharacter.f90(26) : Error: A CHARACTER data type is required in this context. [NEWCOL]
ARRAKY=NEWCOL
---------------^
Error executing df.exe.integercharacter.obj - 1 error(s), 0 warning(s)
So it is a mystery to me that you can get your code to even compile.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Looking at the second piece of code you posted
character*16 arraky
arraky = ' '
write(arraky,*) newcollision
arraky = trim(arraky)//char(0)
If newcollision is 20 then arraky should be 10 spaces followed by '20' followed by char(0) (I've just written a small test program to do just that)
Where are you "printing" the value of arraky?Could you be passing a string of length 16 (arraky) to a subroutine but in that subroutine you have declared the dummy argument to be longer than 16 andprintingthat string? which produces the "squares" (which are merely a substitute for unprintable characters) If so then you should declare the dummy argument to be character(*) string_name.
Another thought : with the internal write you could replace the * with '(i0)' which will left justify the string if you required that.
Les
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Gracias, Les, i think u found the problem with the squares, the LVG have the Character butwith a size of72, so if i am not wrong i should declared in newcol as 72.
Another point just because ive no idea how char * works in Fortran, instead of declaring the char 72 i can do it like char *, but shouldn't i to reserve the memory, like in C using malloc??
Thanks.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
OK. You should either :
declare arraky as character(72)
or change LVG to declare the passed in string as character(*) (always assuming the LVG routine is also Fortran)
The second option is better since you call LVG from elsewhere
ie from SETMOL (and possibly other places?) where NEWMOL is declared as character(20). If you cannot change LVG for some reason,then you need to change NEWMOL to character(72) AND change whatever subroutine(s) calls SETMOLso that theypass a character(72) string and so on up the chain.
You do not need to "malloc" any space in Fortran forthe character string as the declaration "CHARACTER(72) :: ARRAKY" does it for you.
If you can get the Fortran routines sorted out then you can start to look at the interface to the C routines. Though it might be worth pointing out that the string coming from C will presumably have a char(0) at the end of it. This won't cause any problem to Fortran but you may need to process the string to replace it with a blank and pad the remainder of the string with blanks too.Alsoif you are passing a string from Fortranto C to allow an extra character for the null terminator.
Les
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thanks a lot guys,
as i wrote, your suggestion are working, and you save my head. Thanks
I do not want to be exasperating, but i have to implement a last thing i am getting some troubles. I am sending some char * to fortran from c but fortran is receiving again some unreadable messages. I can not find the sol.
Thanks
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
OK I have something where I call Fortran from c++ but should be similar.
Fortran code :
integer*4 function DFOpenClt(cltFileSpec, bIsNew)
character(len=200), intent(in):: cltFileSpec
integer*4, intent(in) :: bIsNew
... code ...
end function
c++ code
extern "C" {
int __stdcall DFOpenClt(char* FileSpec, UNIT iLen, int isnew)
}
char sFile[200];
int lWriteFile = 1;
(build file name in sFile and set iLen to length of string)
nError = DFOpenClt(sFile, iLen, &lWriteFile);
(where iLen is the length of the string sFile)
Hope this helps
Les

- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page