- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi all,
I have an Intel Visual FORTRAN Compiler together with an Intel C++ Compiler (parallel studio xe 2018 professional) in the Microsoft Visual Studio Professional 2017.
Usually I program in FORTRAN 95, But I have some codes in c from other sources. Because of that I need to integrate c-functions in my fortran programm,
But I don't know how. I know there is an example in the mixed language help (fortran calles c). But there is no instruction how to start (how to create this in VS) and build this and on the other hand the example is about subroutines and not about functions. Iin addition some functions have errorhandler, (some not). So I need to know how I can realize solving both types
Would someone help me?
Olaf
Link Copied
- « Previous
-
- 1
- 2
- Next »
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi mecej4,
thank you for your answer.
Yes, I do have the .lib-file (the name is PPSystem.lib and I have it in "additional dependency" in "configuration properies".)
About Line 73 in #19 you wrote, that my linker problems relate to using an external symbol (which is a constant address once the program has been loaded) and a pointer to the same external symbol, on the Fortran side". But what can I do?
Olaf
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The key points are to make pErrorHandlerFct a pointer and to make it point to the external routine ErrorHandlerFct. The former is a variable whose value is some routine address. The latter is a constant address whose value is supplied by the linker.
The statement
pErrorHandlerFct => ErrorHandlerFct
in #19 copies the linker-supplied address into the pointer variable, and that variable can then be passed as the last argument to fhpt(). The argument is of the correct type, is a variable as the interface specifies, and has been set to point to the correct target.
P.S. I now realize that it may be confusing to follow advice from two people at the same time. Please follow Steve's directions. I am sure that he will help you resolve the problems that you have been experiencing.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
You didn't do what I suggested. Replace this line:
myH2S, myN2, myO2, mySO2, pErrorHandlerFct))
with:
myH2S, myN2, myO2, mySO2, ErrorHandlerFct))
You will have no reference to pErrorHandlerFct in your code. Instead you are referencing the module procedure ErrorHandlerFct. There is no need for a pointer.
Please do this to help us diagnose the link issue. Open a Fortran Build Environment command prompt (in the Start menu under Intel Parallel Studio 20xx, Compiler 19.x for IA-32). Set default (cd) to the folder containing PPSystem.lib. If this is a static library, type the command:
dumpbin -symbols -exports PPSystem.lib > lib.txt
Attach lib.txt to a reply here.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Steve, hi mecej4,
in wich line you mean the changing from myH2S, myN2, myO2, mySO2, pErrorHandlerFct)) to myH2S, myN2, myO2, mySO2, ErrorHandlerFct)).
And if it is in my main program (ig. #17, line 79 or 80), wich definition of the variable I do need?
For the diagnose earliest I have time tomorrow.
Greetings, Olaf
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Yes, I did miss the p and t arguments. As I guessed, your library assumes the STDCALL interface. Use this instead:
interface function fhpt (p, t, myWATER, myAR, myC2H6, myC3H8, myCH4, myCO, myCO2, myH2, myH2O, & myH2S, myN2, myO2, mySO2, pErrorHandlerFct) BIND(C) import real(C_DOUBLE) :: fhpt !DEC$ ATTRIBUTES STDCALL :: fhpt real(C_DOUBLE), VALUE, INTENT(IN) :: p real(C_DOUBLE), VALUE, INTENT(IN) :: t real(C_DOUBLE), VALUE, INTENT(IN) :: myWATER real(C_DOUBLE), VALUE, INTENT(IN) :: myAR real(C_DOUBLE), VALUE, INTENT(IN) :: myC2H6 real(C_DOUBLE), VALUE, INTENT(IN) :: myC3H8 real(C_DOUBLE), VALUE, INTENT(IN) :: myCH4 real(C_DOUBLE), VALUE, INTENT(IN) :: myCO real(C_DOUBLE), VALUE, INTENT(IN) :: myCO2 real(C_DOUBLE), VALUE, INTENT(IN) :: myH2 real(C_DOUBLE), VALUE, INTENT(IN) :: myH2O real(C_DOUBLE), VALUE, INTENT(IN) :: myH2S real(C_DOUBLE), VALUE, INTENT(IN) :: myN2 real(C_DOUBLE), VALUE, INTENT(IN) :: myO2 real(C_DOUBLE), VALUE, INTENT(IN) :: mySO2 procedure(HANDLERPROC) :: pErrorHandlerFct end function fhpt end interface
It was line 80 that I suggest you modify, in conjunction with the code I supplied. You will not have any reference to pErrorHandlerFct except in the interface block.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Steve, it works!!!!!!!!!!!!!!!!!
At least with including the STDCALL --> !DEC$ ATTRIBUTES STDCALL :: fhpt in the interface definition (how you wrote in #27) the linking was without problems and I get the accurate result now. I'm so happy.
There is only one thing (or two things) witch would be useful in addition: If I could read the errorhandler (at lest the value "code") I could react. The variable "errorhandlerFct" has currently no data type. And if there would be a solution, I could use IMPLICIT NONE in my main progam. Do you know how?
But wether with the content of the errorhandler or without: thank you Steve, thanks even to mecej4
Olaf
ps: Here is my full code now:
module fhpt_mod use, intrinsic :: iso_c_binding implicit none abstract interface subroutine HANDLERPROC (code, string) BIND(C) import integer(C_INT), VALUE :: code character, dimension(*) :: string end subroutine HANDLERPROC end interface interface function fhpt (p, t, myWATER, myAR, myC2H6, myC3H8, myCH4, myCO, myCO2, myH2, myH2O, & myH2S, myN2, myO2, mySO2, pErrorHandlerFct) BIND(C) import real(C_DOUBLE) :: fhpt !DEC$ ATTRIBUTES STDCALL :: fhpt real(C_DOUBLE), VALUE, INTENT(IN) :: p real(C_DOUBLE), VALUE, INTENT(IN) :: t real(C_DOUBLE), VALUE, INTENT(IN) :: myWATER real(C_DOUBLE), VALUE, INTENT(IN) :: myAR real(C_DOUBLE), VALUE, INTENT(IN) :: myC2H6 real(C_DOUBLE), VALUE, INTENT(IN) :: myC3H8 real(C_DOUBLE), VALUE, INTENT(IN) :: myCH4 real(C_DOUBLE), VALUE, INTENT(IN) :: myCO real(C_DOUBLE), VALUE, INTENT(IN) :: myCO2 real(C_DOUBLE), VALUE, INTENT(IN) :: myH2 real(C_DOUBLE), VALUE, INTENT(IN) :: myH2O real(C_DOUBLE), VALUE, INTENT(IN) :: myH2S real(C_DOUBLE), VALUE, INTENT(IN) :: myN2 real(C_DOUBLE), VALUE, INTENT(IN) :: myO2 real(C_DOUBLE), VALUE, INTENT(IN) :: mySO2 procedure(HANDLERPROC) :: pErrorHandlerFct end function fhpt end interface ! Variables that hold the last value from an error handler function integer(C_INT) :: error_code = -1 integer, parameter :: max_error_string_len = 80 character(max_error_string_len) :: error_string = '' contains subroutine ErrorHandlerFct (code, string) BIND(C) integer(C_INT), VALUE :: code character :: string(*) integer i ! Store code error_code = code ! Determine C string length error_string = "" do i=1,max_error_string_len+1 if (string(i) == C_NULL_CHAR) exit error_string(i:i) = string(i) end do end subroutine ErrorHandlerFct end module fhpt_mod !**************************************************************************** program prop_C_to_Fort_01 use fhpt_mod double precision :: fhtp, p, t, myWATER, myAR, myC2H6, myC3H8, myCH4, myCO, myCO2, myH2, & myH2O, myH2S, myN2, myO2, mySO2 p=1.0; t=50.0; myWATER=1.0; myAR=0.0; myC2H6=0.0; myC3H8=0.0; myCH4=0.0; myCO=0.0 myCO2=0.0; myH2=0.0; myH2O=0.0; myH2S=0.0; myN2=0.0; myO2=0.0; mySO2=0.0 os_cpp_fhpt = dble(fhpt (p, t, myWATER, myAR, myC2H6, myC3H8, myCH4, myCO, myCO2, myH2, myH2O, & myH2S, myN2, myO2, mySO2, ErrorHandlerFct)) end program prop_C_to_Fort_01
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
>>If I could read the errorhandler (at lest the value "code") I could react.
In your post #15 you show an example of what you pass in for "code".
This illustrates that you have defined the values for "code".
*** your possible use of code:
! after you capture error_string if(code >= 0) then ! fatal error code ... ! any shutdown code STOP "Fatal Error Message Here" endif ! code < 0 == recoverable error ... ! any error logging code return
That is just a suggestion.
Example use
... (after saving error_string) if (abs(d) ==0) { pErrorHandlerFct(0, “Division by zero!”); } if (abs(d) =< 1.e-12) { pErrorHandlerFct(-1, “Division overflow”); // log warning ReturnValue = DBL_MAX; // or use some very large special value that you define // e.g. 9999999999.99 } else { ReturnValue = a/d; // #15 had /b in error }
Jim Dempsey
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Jim,
no, I asked about the program who calls the c-function. There (in the main programm "prop_C_to_Fort_01") I like to read the feedback "ErrorHandlerFct". Currenty this variable has not a data type declaration and because of that no value in my main.
Olaf
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
ErrorHandlerFct is not a variable, it is a subroutine defined in the module I had you create. The subroutine stores the error code and the error string in module variables error_code and error_string, which you can reference after the call to fhpt.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Yes Steve, that's really great, your informations are all really great
direct access to error_code and error_string in the main I didn't get in the debugger (although I have a use to the fhpt_mod), but with
ecode=error_code
estring=error_string
I have access with no problem. But not really without any problem: the program crashes rigorous, if ig. wrong values are handled down to the c-function.
Can I intercept that?
Olaf
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
No, you can't intercept what happens in the C function.
In the debugger you can do a QuickWatch on fhpt_mod::error_code, etc.
Remember that you'll want to reset error_code to -1 before each call to fhpt.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
OK, thank you, thank you for all
Olaf
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Steve,
if ig. a wrong value is handled down to the c-routine, it does not crash. It only gives back something via the ErrorHandlerFct (I asked the dealer of the program wich includes the c-routine).
So the crash maybe comes from the connecton to fortran.
Attached you see the crash report in the debugger, but there is no other possibilities to get informations from the debugger.
Do yo have some further idea what I can do?
Greetings, Olaf
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Steve again, sorry,
there is a new problem with the whole program:
After including the STDCALL --> !DEC$ ATTRIBUTES STDCALL :: fhpt (look #28, line19) I got the right return value in
line 79 yesterday.
But as I recognized today it works only in the debugger linking, not in release linking.
While release linking the errors are:
fatal error LNK1120: 1 nicht aufgelöste Externe Release\prop_C_to_Fort_02.exe
error LNK2019: Verweis auf nicht aufgelöstes externes Symbol "_fhpt@124" in Funktion "_MAIN__". prop_C_to_Fort_02.obj
But I need this version, would you help me again?
Olaf
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
When you added the library to Additional Dependencies, the default was that it was only for the Debug configuration. You need to do it again for Release. Next time, for something like this, select "All Configurations".
The error is an access violation. There are many possible causes of this, not something one can diagnose from a screenshot.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Steve, thank you again, this solved my problem on point, thanks.
Olaf
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page
- « Previous
-
- 1
- 2
- Next »