- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Folks,
I have an F90 shared object library compiled with the Intel FORTRAN compiler - don't know what version.
I have a C++ driver compiled with the Gnu compiler (v4.4.7) which can link against the fortran library fine.
I'm trying to recompile the fortran library so I can trace through it with a debugger (and eventually to modify it). I'm using ifort Version 16.0.0.109 Build 20150815.
However, when I attempt to run the driver with the recompiled library, I get an error passing arguments into a subroutine. The function prototype is as follows:
subroutine set_some_params(Dir, bufSize,Mode, flag1, flag2, param1, param2, param3) !DEC$ IF DEFINED(_WIN32) !DEC$ ATTRIBUTES DLLEXPORT, DEFAULT, ALIAS:'set_some_params' :: set_some_params !DEC$ ELSE !DEC$ ATTRIBUTES ALIAS:'set_some_params' :: set_some_params !DEC$ END IF implicit none character(FILEPATHLEN), intent(in) :: Dir ! directory path integer, value :: bufSize ! buffer size [5000] integer, value :: Mode ! run mode integer, value :: flag1 integer, value :: flag2 real(8), value :: param1 integer, value :: param2 integer, value :: param3 ...
This is the first call of a fortran library function, and it crashes. Loading the exe & core file into gdb shows the failure where the bufSize parameter is first used.
Printing the Dir variable in gdb shows the expected value, however the rest of the arguments I get the following:
(gdb) p bufSize
Cannot access memory at address 0x1388
(gdb) p Mode
Cannot access memory at address 0x0
(gdb) p flag1
Cannot access memory at address 0x0
(gdb) p flag2
Cannot access memory at address 0x0
etc.
The ifort compile command looks like this:
/usr/local/bin/ifort -D_LINUX64 -g -c -u -r8 -i4 -fPIC -fpp1 -reentrancy -threads -recursive -fopenmp ../../Source_F/some_file.f90 -o some_file.o
Which produces the following warning:
ifort: command line remark #10128: invalid value '1' for '-fpp'; ignoring
The library link line looks like this:
/usr/local/bin/ifort -D_LINUX64 -V -fPIC -shared --reentrancy -threads -recursive -fopenmp -o ../../../lib_x64/some_lib.dll ./some_file.o ./some_file2.o ./some_file3.o -L. -L/opt/intel/lib/intel64/ -i-dynamic -lifport -lifcore -limf -lsvml -lintlc
I get the following warnings here:
ifort: command line warning #10006: ignoring unknown option '-freentrancy'
ifort: command line remark #10148: option '-i-dynamic' not supported
And the -L path /opt/intel/lib/intel64/ doesn't exist on my system, but it apparently doesn't need anything there.
The C++ command line:
g++ -g -m64 driver.cc -o driver ./DllUtils.o ./DllMainDll.o -ldl -lc -lm
where DllUtils.o and DllMainDll.o are C++ object files that specify some helper functions and interfaces to the shared object library. Sorry about the "Dll" notation - that's from the original developer.
The header file, DllUtils.h contains the following:
typedef void (STDCALL *fnPtrset_some_params)(char Dir[512], int bufSize, int Mode, int flag1, int flag2, double param1, int param2, int param3);
So to summarize - the original library works fine. When I attempt to recompile the library using the original makefiles (modified for different path to ifort only) I get an error passing arguments. First argument (pointer) is OK, the rest fail.
Sorry this is so vague - it's a huge project, I'm trying to extract what may be relevant here. This is on a CentOS 6 box
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The VALUE behavior did change a couple of releases ago. We were incorrectly implementing it. There's an option -assume nostd_value if you want the old behavior.
If you want to use BIND(C) then you should remove the ATTRIBUTES directives entirely. But as I mentioned, the CHARACTER declaration with a length other than 1 won't be accepted. (For C interoperability, one would declare this as CHARACTER(1), DIMENSION(*)).
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The VALUE attribute doesn't mean "pass (or accept) by value" unless the procedure also has BIND(C).
I'd suggest the simple fix of adding BIND(C) to the Fortran routine (it goes after the argument list on the SUBROUTINE line), but then your use of CHARACTER(FILEPATHLEN) would be disallowed.
If one is willing to stray further from the standard, add "MIXED_STR_LEN_ARG,C," before "ALIAS" in both directives( and remove DEFAULT on the WIndows side). I think this will do what you want.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Is the BIND(C) thing something that has changed between compiler releases or such? Because this code worked as written with a different version of the Intel fortran compiler.
When I add BIND(C) as suggested:
subroutine set_some_params(geoDir, bufSize, runMode, savePartials, isSpectr, consider, decayAlt, outCoord) BIND(C) !@ES !DEC$ IF DEFINED(_WIN32) !DEC$ ATTRIBUTES DLLEXPORT, DEFAULT, ALIAS:'set_some_params' :: set_some_params !DEC$ ELSE !DEC$ ATTRIBUTES ALIAS:'set_some_params' :: set_some_params !DEC$ END IF
I get the following error:
error #8143: The BIND(C) attribute for this symbol conflicts with a DEC$ ATTRIBUTES ALIAS, DECORATE, CVF, C, [NO_]MIXED_STR_LEN_ARG or REFERENCE attribute for this symbol. [SET_SOME_PARAMS]
!DEC$ ATTRIBUTES ALIAS:'set_some_params' :: set_some_params
-----------------------------------------------------------^
Thanks!
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The VALUE behavior did change a couple of releases ago. We were incorrectly implementing it. There's an option -assume nostd_value if you want the old behavior.
If you want to use BIND(C) then you should remove the ATTRIBUTES directives entirely. But as I mentioned, the CHARACTER declaration with a length other than 1 won't be accepted. (For C interoperability, one would declare this as CHARACTER(1), DIMENSION(*)).
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
That did it! The binaries I have must have been compiled with a release that used the incorrect behavior. Using -assume nostd_value replicates it for my version of the compiler. They'll have to modify quite a bit of code when they upgrade compilers.
Thanks for the help!
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page