- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Dear forumers,
After researches about pipes on the forum, i didn't find the answer to this question:
I try to use named pipes between C++ (Writes in the pipe)and Fortran (reads in the pipe)executables.Data Transferworks great but I have a problem with the END statement of the FortranREAD command. In fact, the END is never reached under windows.
Small dummy example:
C++:
In the example, the do while(.TRUE.) loop is problematic. Infact, the END=100 statement is never reached.
I have tested the principle under linux versionwithout any problem.
Do i miss something?
Thank you
After researches about pipes on the forum, i didn't find the answer to this question:
I try to use named pipes between C++ (Writes in the pipe)and Fortran (reads in the pipe)executables.Data Transferworks great but I have a problem with the END statement of the FortranREAD command. In fact, the END is never reached under windows.
Small dummy example:
C++:
[cpp]#includeFortran:
#include
int main(){
std::cout << "server opened" <<:ENDL>
char data[500];
DWORD numWritten = 0 ;
HANDLE hPipe;
/*Will write to hPipe*/
LPTSTR lpszPipename = TEXT("\\.\pipe\mynamedpipe");
hPipe = CreateNamedPipe(lpszPipename,PIPE_ACCESS_OUTBOUND | FILE_FLAG_FIRST_PIPE_INSTANCE,
PIPE_TYPE_BYTE | PIPE_WAIT, PIPE_UNLIMITED_INSTANCES,256, 256, 100000, NULL);
std::cout << "pipe created" << std::endl;
if (hPipe != NULL) {
ConnectNamedPipe(hPipe, NULL);
std::cout << "client connected" << std::endl;
strcpy(data,"textern");
WriteFile(hPipe,data,strlen(data),&numWritten,NULL);
strcpy(data,"texte 10 15.8rn");
WriteFile(hPipe,data,strlen(data),&numWritten,NULL);
strcpy(data,"105rn");
WriteFile(hPipe,data,strlen(data),&numWritten,NULL);
strcpy(data,"avant derniere lignern");
WriteFile(hPipe,data,strlen(data),&numWritten,NULL);
strcpy(data,"derniere ligne");
WriteFile(hPipe,data,strlen(data),&numWritten,NULL);
//end of file
data[0] = EOF;
WriteFile(hPipe,data,1,&numWritten,NULL);
std::cout << "Prepare to flush" << std::endl;
FlushFileBuffers(hPipe);
std::cout << "information sent" << std::endl;
Sleep(1000000);
DisconnectNamedPipe(hPipe);
CloseHandle(hPipe);
}
else
std::cerr << "pipe not created" <<:ENDL>
std::cout << "server closed" <<:ENDL>}
[/cpp]
[cpp]program test IMPLICIT none CHARACTER LINE*120 integer I,f, stat REAL*4 Y !lecture direct du fichier f=51 open(f,file='\.pipemynamedpipe',status='UNKNOWN', * form='FORMATTED',ACTION='READ') !ligne de texte de longueur inconnue read(f,'(A120)') LINE write(*,*) LINE !types et longeur connu read(f,'(A5,1X,I2,1X,F4.1)') LINE, I, Y write(*,*) LINE,' ',I,' ',Y !lecture texte jusqu' la fin de fichier do while (.TRUE.) read(f,'(A120)', END=100) LINE write(*,*) LINE end do 100 continue close(f) end program [/cpp]
In the example, the do while(.TRUE.) loop is problematic. Infact, the END=100 statement is never reached.
I have tested the principle under linux versionwithout any problem.
Do i miss something?
Thank you
Link Copied
3 Replies
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Remove the Sleep in the C++ code following the FlushFileBuffers.
The DisconnectNamedPipe will cause the next read on the named pipe to fail. But your code does not issue the DisconnectNamedPipe until after the sleep (1000 seconds)
What I do not know, and will require experimentation on your part, is your Fortran side is performing a blocked read on the pipe handle. i.e. this read is already pending (i.e. will not be next read). The MSVC documentation does not state if this causes an EOF on pending ReadFiles, it only states error on next ReadFile. You may have to address that with some other means. Such as writing an end of file signature record or using a non-blocking read mode on the Fortran side and handling empty data (record of length=0)
Jim Dempsey
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Quoting - jimdempseyatthecove
Remove the Sleep in the C++ code following the FlushFileBuffers.
The DisconnectNamedPipe will cause the next read on the named pipe to fail. But your code does not issue the DisconnectNamedPipe until after the sleep (1000 seconds)
What I do not know, and will require experimentation on your part, is your Fortran side is performing a blocked read on the pipe handle. i.e. this read is already pending (i.e. will not be next read). The MSVC documentation does not state if this causes an EOF on pending ReadFiles, it only states error on next ReadFile. You may have to address that with some other means. Such as writing an end of file signature record or using a non-blocking read mode on the Fortran side and handling empty data (record of length=0)
Jim Dempsey
Dear Jim,
I agree with your analysis, your are totally right with the Sleep.
However, concerning the EOF detection, you see in C++ side i have explicitly added an EOF in the pipe.
If i replace the do while loop in Fortran by:
[cpp] do while (.NOT.EOF(f)) read(f,'(A100)') LINE end do[/cpp]
The detection succeeds. I really wonder why the END statement in READ function does not reach to do the same job.
Sincerely yours,
F-Xavier
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Don't know.
On the C++ size, read and write to pipe sufficient number of lines to get into your do while(.not.EOF(f)) loop but with additional lines to read and write to pipe. Then break on the C++ side (assuming seperate app). Then run the Fortran side. The test will be to get the Fortran side to out pace the pipe fill side. This is to test for EOF(f) returning true for empty pipe as opposed to following DisconnectNamedPipe.
Should EOF(f) return true on empty pipe, then the code you have above is incorrect (when reader of pipe out paces writer of pipe). Do not assume writer will always run faster than reader because writer may get preempted by O/S.
I think, in abstract terms, a named pipe as structured in your applications,will behave like a shared sequential file. The writer can write any number of bytes into the file, and the reader can read up to the number of bytes written. When read is attempted past number of bytes written and EOF is returned. This EOF is not necessarily an indication that the writer has completed writing to the "file" (pipe). EOF(f) therefor should be an indication that either a) read out paced writes, or b) writer is in process of finishing off file. So, your code needs to handle both cases. Something like
123 continue
if(EOF(f)) then
INQUIRE(f, OPENED=I_OPENED)
if(.NOT. I_OPENED) GOTO PipeClosed
Sleep(10) ! assume outpaced writer
Goto 123
endif
read(f, ...
Jim Dempsey

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