Prev: Fortran novice
Next: Incorrect values calling F from C
From: halvor.lund on 21 Jun 2007 02:39 I'm trying to make a DLL with Watcom Fortran 77 v.11. My first approach was to export the function using *$pragma aux functionname export. When passing integers by reference to this DLL function, a totally different number reached the function. My second approach was to combine Watcom C and Fortran in the same DLL, with the C part acting as an interface. A C function is exported in the DLL, and this function in turn calls the Fortran function. This solution made passing of variables possible, but caused another problem, which is that the Fortran part of the DLL apparently is not allowed to write to files. I hope some of you can give me the clues I need to at least make one of the approaches work.
From: gsal on 21 Jun 2007 05:31 I personally don't use DLL, I just use static libraries; in any case, I don't see this matter making the difference. Also, I have never needed to use $pragma...what does that do you? If the library's procedure that I want to use is a function, I simply declared it in my program; if the library's procedure is a subroutine, I do nothing. I have run into bugs that sound exactly like yours: numeric argument's value does not make it through correctly into a library. Let's say that you are trying to pass a Unit number to a subroutine in a library, for it, in turn, to write to that file (I do this all the time). Whenever that happens to me, it is because the size of INTEGER in the library is different to the size of INTEGER in my program. So, make sure both programs are compiled with the same size. You can control this by having the same flag (in the makefile) during compilation. Unless, of course, the size is hard coded; so look out for variable declarations like INTEGER*4 and the like. Also, just recently, I run into a problem where I was controlling the type size via compiler flag during compilation but it was only affecting explicitly declared variables (with REAL and INTEGER) but not implicitely declared arrays placed in a DIMENSION block. Hope this helps. gsal
From: halvor.lund on 21 Jun 2007 08:51 On 21 Jun, 11:31, gsal <salger...(a)gmail.com> wrote: > I personally don't use DLL, I just use static libraries; in any case, > I don't see this matter making the difference. Also, I have never > needed to use $pragma...what does that do you? If the library's > procedure that I want to use is a function, I simply declared it > in my program; if the library's procedure is a subroutine, I do > nothing. Using the Watcom IDE, it was the only way I was able to tell the compiler which functions should be exported. Without "*$pragma aux functionname export", it always complained that there were no exports. > Whenever that happens to me, it is because the size of INTEGER in > the library is different to the size of INTEGER in my program. Thanks for your answer, but I'm afraid I've tried what you are suggesting. I too thought of the possibility that the data types had different sizes, but even when specifically specifying INTEGER*4 (corresponding to sizeof(int)==4) I had the same problem. When sending integers from C to the fortran DLL function, it always recieved 0. When sending references to integers from C to the fortran DLL function, it always recieved the same number, regardless of which integer originally sent. Very strange, if you ask me...
From: dpb on 21 Jun 2007 09:14 halvor.lund(a)gmail.com wrote: > On 21 Jun, 11:31, gsal <salger...(a)gmail.com> wrote: >> I personally don't use DLL, I just use static libraries; in any case, >> I don't see this matter making the difference. Also, I have never >> needed to use $pragma...what does that do you? If the library's >> procedure that I want to use is a function, I simply declared it >> in my program; if the library's procedure is a subroutine, I do >> nothing. > > Using the Watcom IDE, it was the only way I was able to tell the > compiler which functions should be exported. Without "*$pragma aux > functionname export", it always complained that there were no exports. > >> Whenever that happens to me, it is because the size of INTEGER in >> the library is different to the size of INTEGER in my program. > > Thanks for your answer, but I'm afraid I've tried what you are > suggesting. I too thought of the possibility that the data types had > different sizes, but even when specifically specifying INTEGER*4 > (corresponding to sizeof(int)==4) I had the same problem. > > When sending integers from C to the fortran DLL function, it always > recieved 0. > When sending references to integers from C to the fortran DLL > function, it always recieved the same number, regardless of which > integer originally sent. Between Fortran and C the convention is by value for C for an int by default but by reference for Fortran. You need to make both expect the same via pragma directive(s). It's been long enough since I've used Watcom I don't recall the form and don't have it installed on this machine to look. IIRC there are examples in the Watcom doc's on making simple DLLs that should provide the roadmap. If that fails you may get more specific input in the OW forum. --
From: Kevin G. Rhoads on 21 Jun 2007 11:04
The Watcom Fortran run-time library (RTL) is built on the Watcom C/C++ RTL. Any I/O done in a single target (whether EXE or DLL) that includes both C and F77 should be limited to one or the other. I.e., if you do I/O from C, then don't do it from F77 and vice versa. This means if a file is opened in one (C or F77) it should be read/written and closed from the same language. It is possible to break this rule of thumb with Watcom (& OpenWatcom) and make it work, but that requires getting into compiler specific arcana. I've been there with several (including Watcom 10.6 and 11.0) and do not recommend it. It is possible without too much fuss to open, read/write, close files in both the C and F77 if you can be sure that you will NEVER touch the same file from both sides. Once you start diddling any file from both C and F77, even sequentially, not simultaneously, it gets you into the arcane stuff. So, in general, for ease and portability, limit I/O to one or the other. |