- 신규로 표시
- 북마크
- 구독
- 소거
- RSS 피드 구독
- 강조
- 인쇄
- 부적절한 컨텐트 신고
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
링크가 복사됨
10 응답
- 신규로 표시
- 북마크
- 구독
- 소거
- RSS 피드 구독
- 강조
- 인쇄
- 부적절한 컨텐트 신고
> 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
- 신규로 표시
- 북마크
- 구독
- 소거
- RSS 피드 구독
- 강조
- 인쇄
- 부적절한 컨텐트 신고
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
- 신규로 표시
- 북마크
- 구독
- 소거
- RSS 피드 구독
- 강조
- 인쇄
- 부적절한 컨텐트 신고
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.
- 신규로 표시
- 북마크
- 구독
- 소거
- RSS 피드 구독
- 강조
- 인쇄
- 부적절한 컨텐트 신고
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
- 신규로 표시
- 북마크
- 구독
- 소거
- RSS 피드 구독
- 강조
- 인쇄
- 부적절한 컨텐트 신고
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.
- 신규로 표시
- 북마크
- 구독
- 소거
- RSS 피드 구독
- 강조
- 인쇄
- 부적절한 컨텐트 신고
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
- 신규로 표시
- 북마크
- 구독
- 소거
- RSS 피드 구독
- 강조
- 인쇄
- 부적절한 컨텐트 신고
"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