Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.

Passing Null argument

vngsas
초급자
2,524 조회수
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
0 포인트
10 응답
Steven_L_Intel1
2,524 조회수
Pass %val(0).

Steve
0 포인트
vngsas
초급자
2,524 조회수
> 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.
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
0 포인트
Steven_L_Intel1
2,524 조회수
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
0 포인트
llynisa
초급자
2,524 조회수
I am curious to know why, if the argument is optional, you cannot just omit it.

Alan
0 포인트
Jugoslav_Dujic
소중한 기여자 II
2,524 조회수
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.
0 포인트
dave_frank
초급자
2,524 조회수
Isnt the integer declaration illegal? %val(0)
0 포인트
Steven_L_Intel1
2,524 조회수
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
0 포인트
vngsas
초급자
2,524 조회수
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.
0 포인트
Jugoslav_Dujic
소중한 기여자 II
2,524 조회수
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:
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
0 포인트
Steven_L_Intel1
2,524 조회수
"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
0 포인트
응답