- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi All,
I am calling a C dll from Fortran (Microsoft fortran IV). A particular function in the dll has four arguments with last argument being an optional one, which should be declared as an NULL. I am not able to declare in my fortran declaration this argument as an NULL, as it gives an error. I don't know what is the syntax to pass this argument as a NULL. Any help will be greatly appreciated, if i am not clear, i will clarify with the actual code.
thank you
I am calling a C dll from Fortran (Microsoft fortran IV). A particular function in the dll has four arguments with last argument being an optional one, which should be declared as an NULL. I am not able to declare in my fortran declaration this argument as an NULL, as it gives an error. I don't know what is the syntax to pass this argument as a NULL. Any help will be greatly appreciated, if i am not clear, i will clarify with the actual code.
thank you
Link Copied
10 Replies
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Pass %val(0).
Steve
Steve
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
> Pass %val(0).
>
> Steve
Hi Steve,
It gives an syntax error, i don't know if iam giving your syntax correctly. I am attaching the code below,
EPANET2 is an C dll, ENepanet is a function in that, which needs four arguments, the last one being the optional, which should be passed as an NULL.
>
> Steve
Hi Steve,
It gives an syntax error, i don't know if iam giving your syntax correctly. I am attaching the code below,
EPANET2 is an C dll, ENepanet is a function in that, which needs four arguments, the last one being the optional, which should be passed as an NULL.
C calling epanet test program
PROGRAM CALLEPA
INTEGER iENepanet(1,7,8,%val(0))
INTERFACE
SUBROUTINE EPANET2(ENepanet)
!MS$ATTRIBUTES DLLIMPORT :: EPANET2
!MS$ATTRIBUTES C, ALIAS: "_ENepanet@16" ::EPANET2
INTEGER ENepanet(1,7,8,%val(0))
END SUBROUTINE EPANET2
END INTERFACE
OPEN(UNIT=1,FILE='new.inp')
OPEN(UNIT=7,FILE='new.out')
OPEN(UNIT=8,FILE='new.bin')
CALL EPANET2(iENepanet)
END
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I can see part of your confusion, but need more info to decide what you need to write. The best thing would be if you could give the C header for the EPANET2 and ENepanet routines - or are these two separate routines? The code you have doesn't match your text description and I'm not sure which pieces of which to accept.
Steve
Steve
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I am curious to know why, if the argument is optional, you cannot just omit it.
Alan
Alan
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I suspect, since the original poster mentioned "C dll", that he needs !DEC$ATTRIBUTES C, VARYING for the routine, rather than a Fortran OPTIONAL argument, which is quite a different beast. However, it's just a speculation as well -- we really need more data.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Isnt the integer declaration illegal? %val(0)
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
There's lots wrong in the code as posted. But as I'm not clear just what is wanted, I hesitated to suggest a correction.
What I think we have is a routine which accepts another routine as an argument. To use INTERFACEs fully, the routine actually called needs to have a nested INTERFACE that describes the procedure argument, then the routine passed needs to have its own INTERFACE so that they match. But it is not clear to me how many routines we're talking about.
If you are declaring a C routine that can accept a NULL argument, one can declare it as OPTIONAL or just as an INTEGER(4) passed by value.
Steve
What I think we have is a routine which accepts another routine as an argument. To use INTERFACEs fully, the routine actually called needs to have a nested INTERFACE that describes the procedure argument, then the routine passed needs to have its own INTERFACE so that they match. But it is not clear to me how many routines we're talking about.
If you are declaring a C routine that can accept a NULL argument, one can declare it as OPTIONAL or just as an INTEGER(4) passed by value.
Steve
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thankyou all of you for your posting. Actually I might have prematurely posted code which might have lot of mistakes. Sorry about that, hope you don't mind my amatuerishness! I might have to repharase the question itself.
Epanet2.dll is a dll for water distribution appliction. It is created from a C source. This dll i want to import into fortran. There is no .LIB readily available to link with Fortran.
There are about 50 routines in the dll, in that i want to call a routine called ENepanet, which is declared in C source as given below
int ENepanet( char* f1, char* f2, char* f3, void (*) (vfunc) )
Arguments
f1: name of the input file
f2: name of an output report file,
f3: name of an optional binary output file
vfunc: pointer to a user-supplied function which accepts a character string as its argument.
Vfunc is optional, if i am not passing any argument, i have to pass it as a NULL.
To create .LIB i used borland implib.exe, but when i try to link with fortran (Microsoft powerstation fortran 4.0), it says the lib is corrupted.
So I recompiled the C source with a open source compiler (bloodshed dev c++) as a dll, which gave me a .LIB file
This i linked with fortran by the following command at prompt
fl32 callepa.f /DEFAULTLIB epanet2.lib
This gave me error as LNK2001, Unresolved external symbol _imp_ENpanet.
This i understand is due to name mangling in C, which i came to know from discussion of this forum.
So i used dumpbin to find the name which was _ENepanet@16
this i substituted as given in my posted code, which i am able to compile now.
When i execute it gives a popup error
The instruction at "0x00020220" referenced memory at "0x00000000". The memory could not be "written"
I thought this is because i didn't pass a fourth argument as NULL in my calling routine. That's why i posted the original query.
Now i understand code itself may be wrong, to pass files as arguments.
Any help from you, i will be grateful. Thankyou for giving your time.
Epanet2.dll is a dll for water distribution appliction. It is created from a C source. This dll i want to import into fortran. There is no .LIB readily available to link with Fortran.
There are about 50 routines in the dll, in that i want to call a routine called ENepanet, which is declared in C source as given below
int ENepanet( char* f1, char* f2, char* f3, void (*) (vfunc) )
Arguments
f1: name of the input file
f2: name of an output report file,
f3: name of an optional binary output file
vfunc: pointer to a user-supplied function which accepts a character string as its argument.
Vfunc is optional, if i am not passing any argument, i have to pass it as a NULL.
To create .LIB i used borland implib.exe, but when i try to link with fortran (Microsoft powerstation fortran 4.0), it says the lib is corrupted.
So I recompiled the C source with a open source compiler (bloodshed dev c++) as a dll, which gave me a .LIB file
This i linked with fortran by the following command at prompt
fl32 callepa.f /DEFAULTLIB epanet2.lib
This gave me error as LNK2001, Unresolved external symbol _imp_ENpanet.
This i understand is due to name mangling in C, which i came to know from discussion of this forum.
So i used dumpbin to find the name which was _ENepanet@16
this i substituted as given in my posted code, which i am able to compile now.
When i execute it gives a popup error
The instruction at "0x00020220" referenced memory at "0x00000000". The memory could not be "written"
I thought this is because i didn't pass a fourth argument as NULL in my calling routine. That's why i posted the original query.
Now i understand code itself may be wrong, to pass files as arguments.
Any help from you, i will be grateful. Thankyou for giving your time.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
There are several reasons why it could go wrong. First, exported name _ENepanet@16 suggests that it's a STDCALL routine. Second, you have to take care to handle character arguments correctly. The routine argument is most conveniently mapped to an INTEGER:
I'd warmly recommend that you do yourself a favor and buy a CVF6.6 or Intel7 compiler. FPS is way outdated, unsupported, and buggy.
Jugoslav
INTERFACE INTEGER FUNCTION ENepanet(f1, f2, f3, vfunc) !MS$ATTRIBUTES DLLIMPORT, STDCALL, ALIAS: "_ENepanet@16":: ENepanet !Don't pass hidden length: !MS$ATTRIBUTES REFERENCE:: f1 !MS$ATTRIBUTES REFERENCE:: f2 !MS$ATTRIBUTES REFERENCE:: f3 CHARACTER(*):: f1, f2, f3 INTEGER:: vfunc END FUNCTION END INTERFACE ...Now, you can call it like:
s1="C:BlahBlahInput.txt" ...i = ENepanet(TRIM(s1)//CHAR(0), TRIM(s2)//CHAR(0), TRIM(s3)//CHAR(0), 0)If you need to include callback function, put LOC(MyVFunc) as the 4th argument. Note that MyVFunc, in that case, should have STDCALL (or maybe C) attribute, and REFERENCE attribute for the character argument, (and thus an explicit interface in the main caller).
I'd warmly recommend that you do yourself a favor and buy a CVF6.6 or Intel7 compiler. FPS is way outdated, unsupported, and buggy.
Jugoslav
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
"This gave me error as LNK2001, Unresolved external symbol _imp_ENpanet.
This i understand is due to name mangling in C, which i came to know from discussion of this forum."
No, that's due to not having a DLL import library to link against.
Steve
This i understand is due to name mangling in C, which i came to know from discussion of this forum."
No, that's due to not having a DLL import library to link against.
Steve
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