- 新着としてマーク
- ブックマーク
- 購読
- ミュート
- RSS フィードを購読する
- ハイライト
- 印刷
- 不適切なコンテンツを報告
I'm building a 32-bit app on a 64-bit machine. My two colleagues are building the same app on 32-bit machines. Mine fails while theirs are fine.
I created a simple Fortran routine called Junk to illustrate the problem. The program fails when the 4th variable in the Junk call list is used. The error message is "Dummy character variable 'CHAR4' has length which is greater than the actual variable length -858993460". If I reduce the number of variables in the call list to three, I have no problems.
The dialog is written with C++. It callsthe C routine junkc which calls a Fortran routine Junk. The C routines and Fortran routines are built into seperate DLLs.
SUBROUTINE Junk(char1, char2, char3, char4)
!DEC$ ATTRIBUTES DECORATE, ALIAS:'junk' :: Junk
!DEC$ ATTRIBUTES DLLEXPORT::Junk
CHARACTER(LEN=5), INTENT(IN) :: char1
CHARACTER(LEN=5), INTENT(IN) :: char2
CHARACTER(LEN=5), INTENT(IN) :: char3
CHARACTER(LEN=5), INTENT(IN) :: char4
CHARACTER(LEN=5) :: char1a
CHARACTER(LEN=5) :: char2b
CHARACTER(LEN=5) :: char3c
CHARACTER(LEN=5) :: char4d
char1a = ' '
char2a = ' '
char3a = ' '
char4a = ' '
char1a = char1
char2b = char2
char3c = char3
char4d = char4 ! <--- Program fails here
RETURN
END
The C routine which calls the Fortran routine is called junkc. It uses the routine cluCpFstr to convert C strings to Fortran strings.
void junkc(void)
{
char char1[5+1], char2[5+1], char3[5+1], char4[5+1];
char char1a[5], char2a[5], char3a[5], char4a[5];
strcpy(char1,"abcde");
strcpy(char2,"fghij");
strcpy(char3,"klmno");
strcpy(char4,"pqrst");
cluCpFstr(char1, 5+1, char1a, 5);
cluCpFstr(char2, 5+1, char2a, 5);
cluCpFstr(char3, 5+1, char3a, 5);
cluCpFstr(char4, 5+1, char4a, 5);
junk(char1a, char2a, char3a, char4a);
}
void cluCpFstr(char *src_str,int src_size,char *target_str,int target_size)
{
int i,cplen;
for(i=0;i
cplen = (src_size > target_size) ? target_size : src_size;
for(i=0;i
}
I've tried using all of the compiler diagnostics, but have not been able to solve this problem.
Mike
- 新着としてマーク
- ブックマーク
- 購読
- ミュート
- RSS フィードを購読する
- ハイライト
- 印刷
- 不適切なコンテンツを報告
!DEC$ ATTRIBUTES REFERENCE :: char1,char2,char3,char4
to the Fortran routine. This will tell Fortran not to expect lengths.
コピーされたリンク
- 新着としてマーク
- ブックマーク
- 購読
- ミュート
- RSS フィードを購読する
- ハイライト
- 印刷
- 不適切なコンテンツを報告
!DEC$ ATTRIBUTES REFERENCE :: char1,char2,char3,char4
to the Fortran routine. This will tell Fortran not to expect lengths.
- 新着としてマーク
- ブックマーク
- 購読
- ミュート
- RSS フィードを購読する
- ハイライト
- 印刷
- 不適切なコンテンツを報告
You are right on the money again.
I use the !DEC$ ATTRIBUTES REFERENCE in all of the interfaces I've created for C routines called by Fortran which pass character variables, but I had not used it in Fortran routines called by C.
What I don't understand is why this was all working fine until I compiled on my new 64-bit machine. We probably have a couple of hundred calls to Fortran from C, and a lot of this code has been around for a couple of decades.
Anyway, thank's again.
Mike
- 新着としてマーク
- ブックマーク
- 購読
- ミュート
- RSS フィードを購読する
- ハイライト
- 印刷
- 不適切なコンテンツを報告
I suggest you also start looking at the Fortran 2003 C interoperability features, though one area they are weak in is exactly what you are doing here - calling Fortran with character strings. For an "interoperable" routine, you'd have to declare the character arguments as an array of single characters. You'd then have to TRANSFER those to a character(n) variable to do anything with them. But with BIND(C), you could do away with all the directives save DLLEXPORT.
- 新着としてマーク
- ブックマーク
- 購読
- ミュート
- RSS フィードを購読する
- ハイライト
- 印刷
- 不適切なコンテンツを報告
I have modified 190 Fortran routines called by C to use!DEC$ ATTRIBUTES REFERENCE.It required that Iduplicate 50 of them that arealso called by other Fortran routines so that the character string length was passed.
This should have solved my problem. However, early on in tracking down the problem, I had turned on the Floating Point option toCheck Floating-Point Stack - Yes (/Qfp-stack-check). This had uncovered a couple of errors which I had corrected, and I left it set to Yes.
When I tried to run after correcting everything, I was receiving the runtime error "Unhandled exception at 0x11466286 (CLASH_FsrcD.dll) in CLASH.exe: 0xC0000005: Access violation writing location 0x00000000". The error occured when a local character variable was intialized the second time the routine was called. Setting the Check Floating-Point Stack - No eliminated the error and the program runs correctly.
Mike
- 新着としてマーク
- ブックマーク
- 購読
- ミュート
- RSS フィードを購読する
- ハイライト
- 印刷
- 不適切なコンテンツを報告
extern "C" { void __stdcall junk(char *char1, char *char2, char *char3, char *char4); }
or
extern "C" { void __cdecl junk(char *char1, char *char2, char *char3, char *char4); }
?
- 新着としてマーク
- ブックマーク
- 購読
- ミュート
- RSS フィードを購読する
- ハイライト
- 印刷
- 不適切なコンテンツを報告
extern "C" {__declspec(dllimport) void junk(char1[5], char2[5], char3[5], char4[5]);}
The actual call from C++ would be written like this, the same as from C:
junk(char1, char2, char3, chaqr4);
We have not needed to add a prototype for the Fortran routines called from C.
