<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
	<title type="html"><![CDATA[Approximatrix Forums — Calling a function in C++ dll from FORTRAN]]></title>
	<link rel="self" href="https://forums.approximatrix.com/extern.php?action=feed&amp;tid=246&amp;type=atom" />
	<updated>2013-09-04T17:05:18Z</updated>
	<generator>PunBB</generator>
	<id>https://forums.approximatrix.com/viewtopic.php?id=246</id>
		<entry>
			<title type="html"><![CDATA[Re: Calling a function in C++ dll from FORTRAN]]></title>
			<link rel="alternate" href="https://forums.approximatrix.com/viewtopic.php?pid=960#p960" />
			<content type="html"><![CDATA[<p>Jeff,</p><p>Using VALUE modifier worked in my case. There was one small issue in the C++ side, but the major fix for me was changing the modifier to VALUE. Thanks for your help.</p><p>Regards<br />Sankar</p>]]></content>
			<author>
				<name><![CDATA[sankarnkp]]></name>
				<uri>https://forums.approximatrix.com/profile.php?id=3473</uri>
			</author>
			<updated>2013-09-04T17:05:18Z</updated>
			<id>https://forums.approximatrix.com/viewtopic.php?pid=960#p960</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Re: Calling a function in C++ dll from FORTRAN]]></title>
			<link rel="alternate" href="https://forums.approximatrix.com/viewtopic.php?pid=957#p957" />
			<content type="html"><![CDATA[<p>In your interface, try using the VALUE modifier when declaring your parameters rather than INTENT(IN).&nbsp; I&#039;ve had some better luck with that.&nbsp; Additionally, I noticed that your C declaration says to use the cdecl calling convention.&nbsp; This could theoretically be a problem (DLLs usually use the stdcall convention), but try using the VALUE modifier in your interface declarations first.</p>]]></content>
			<author>
				<name><![CDATA[jeff]]></name>
				<uri>https://forums.approximatrix.com/profile.php?id=2</uri>
			</author>
			<updated>2013-09-01T14:38:56Z</updated>
			<id>https://forums.approximatrix.com/viewtopic.php?pid=957#p957</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Calling a function in C++ dll from FORTRAN]]></title>
			<link rel="alternate" href="https://forums.approximatrix.com/viewtopic.php?pid=956#p956" />
			<content type="html"><![CDATA[<p>Hi,<br />I am stuck at a point where I am using mixed language programming of C++ and FORTRAN. I have a C++ function in a dll which returns a pointer. I tried to call it from my FORTRAN program. I have no problem in compiling, linking and running. However, after the run I get the C pointer returned as 0. It is not a problem with the function in the dl because I have checked with the dll being called from both C++ and C# programs. So I think it is something to dow ith FORTRAN calling the C++ function. Here is the structure of the program:</p><p>// C++ Header<br />// ---------------<br /># include statements</p><p>#ifdef BUILD_DLL<br />&nbsp; &nbsp; #define DLL_EXPORT __declspec(dllexport)<br />#else<br />//&nbsp; &nbsp; #define DLL_EXPORT __declspec(dllimport)<br />#endif</p><br /><p>//#ifdef __cplusplus<br />extern &quot;C&quot;<br />{</p><p>double DLL_EXPORT __cdecl *CalcAirProperties(int InputCombination, double Input1, double Input2, double Pressure);</p><p>}<br />// ---------------</p><p>//C++ source code<br />// ---------------</p><p>double DLL_EXPORT __cdecl *CalcAirProperties(int InputCombination, double Input1, double Input2, double Pressure)<br />{<br />&nbsp; &nbsp; double *AirProperties = new double[7];</p><p>//Do Calculations</p><p>&nbsp; &nbsp;return AirProperties </p><p>}</p><p>// ---------------</p><p>Here is my FORTRAN code:<br />!********************</p><p>PROGRAM ProgramMain</p><p>USE Statements<br />USE iso_c_binding, ONLY : c_ptr,c_double,c_f_pointer</p><p>IMPLICIT NONE</p><p> TYPE(c_ptr) :: c_p<br /> REAL(c_double), POINTER :: f_p(:)</p><p>INTERFACE<br />&nbsp; &nbsp; <br />&nbsp; FUNCTION CalcAirProperties(InputComb, InpValue1,InpValue2,BarometricPressure) BIND(C,NAME=&#039;CalcAirProperties&#039;)<br />&nbsp; &nbsp; &nbsp; <br />&nbsp; &nbsp; &nbsp; USE ISO_C_BINDING<br />&nbsp; &nbsp; &nbsp; <br />&nbsp; &nbsp; &nbsp; INTEGER(kind=C_INT), INTENT(IN)&nbsp; &nbsp; :: InputComb<br />&nbsp; &nbsp; &nbsp; REAL(kind=C_DOUBLE), INTENT(IN)&nbsp; &nbsp; :: InpValue1<br />&nbsp; &nbsp; &nbsp; REAL(kind=C_DOUBLE), INTENT(IN)&nbsp; &nbsp; :: InpValue2<br />&nbsp; &nbsp; &nbsp; REAL(kind=C_DOUBLE), INTENT(IN)&nbsp; &nbsp; :: BarometricPressure<br />&nbsp; &nbsp; &nbsp; <br />&nbsp; &nbsp; &nbsp; TYPE(c_ptr)&nbsp; &nbsp;:: CalcAirProperties</p><p>&nbsp; END FUNCTION<br />&nbsp; <br />END INTERFACE</p><p>&nbsp; &nbsp; REAL :: TempDB_Test<br />&nbsp; &nbsp; REAL :: TempRH_Test<br />&nbsp; &nbsp; REAL :: BaroPressure</p><p>&nbsp; &nbsp; &nbsp; TempDB_Test = 308.15<br />&nbsp; &nbsp; &nbsp; TempRH_Test = 0.69<br />&nbsp; &nbsp; &nbsp; BaroPressure = 101.325<br />&nbsp; &nbsp; &nbsp; <br />&nbsp; &nbsp; &nbsp; c_p = CalcAirProperties(2,TempDB_Test,TempRH_Test,BaroPressure)<br />&nbsp; &nbsp; &nbsp; <br />&nbsp; &nbsp; &nbsp; CALL c_f_pointer(c_p,f_p,[7])<br />&nbsp; &nbsp; &nbsp; <br />&nbsp; &nbsp; &nbsp; RHiC = f_p(3)<br />&nbsp; &nbsp; &nbsp; RhoAiC = f_p(7)</p><p>END ProgramMain</p><p>!********************</p><p>In the above set up the pointer returned by the c_p=CalcAirProperties() call is 0 and thus the values f_p is not pointing to the right array start.</p><p>So to remove all the problems with pointers I converted the C++ function to accept an array (by reference) so that I can set the desired array values inside the C++ function and thus pass the array back to FORTRAN. Here is what I did for that:</p><p>// C++ Header<br />// ---------------<br /># include statements</p><p>#ifdef BUILD_DLL<br />&nbsp; &nbsp; #define DLL_EXPORT __declspec(dllexport)<br />#else<br />//&nbsp; &nbsp; #define DLL_EXPORT __declspec(dllimport)<br />#endif</p><br /><p>//#ifdef __cplusplus<br />extern &quot;C&quot;<br />{</p><p>void DLL_EXPORT __cdecl CalcAirProperties(int InputCombination, double Input1, double Input2, double Pressure,double PropertyArray[]);</p><p>}<br />// ---------------</p><p>//C++ source code<br />// ---------------</p><p>void DLL_EXPORT __cdecl CalcAirProperties(int InputCombination, double Input1, double Input2, double Pressure,double PropertyArray[])<br />{<br />&nbsp; &nbsp; double *AirProperties = new double[7];</p><p>//Do Calculations</p><p>&nbsp; &nbsp; for(int i =0;i&lt;7;i++)<br />&nbsp; &nbsp; {<br />&nbsp; &nbsp; &nbsp; PropertyArray(i) = AirProperties(i);<br />&nbsp; &nbsp; }</p><p>}</p><p>// ---------------</p><p>Here is my FORTRAN code:<br />!********************</p><p>PROGRAM ProgramMain</p><p>USE Statements<br />USE iso_c_binding, ONLY : c_ptr,c_double,c_f_pointer</p><p>IMPLICIT NONE</p><p> TYPE(c_ptr) :: c_p<br /> REAL(c_double), POINTER :: f_p(:)</p><p>INTERFACE<br />&nbsp; &nbsp; <br />&nbsp; SUBROUTINE CalcAirProperties(InputComb, InpValue1,InpValue2,BarometricPressure,PropertyArray) BIND(C,NAME=&#039;CalcAirProperties&#039;)<br />&nbsp; &nbsp; &nbsp; <br />&nbsp; &nbsp; &nbsp; USE ISO_C_BINDING<br />&nbsp; &nbsp; &nbsp; <br />&nbsp; &nbsp; &nbsp; INTEGER(kind=C_INT), INTENT(IN)&nbsp; &nbsp; :: InputComb<br />&nbsp; &nbsp; &nbsp; REAL(kind=C_DOUBLE), INTENT(IN)&nbsp; &nbsp; :: InpValue1<br />&nbsp; &nbsp; &nbsp; REAL(kind=C_DOUBLE), INTENT(IN)&nbsp; &nbsp; :: InpValue2<br />&nbsp; &nbsp; &nbsp; REAL(kind=C_DOUBLE), INTENT(IN)&nbsp; &nbsp; :: BarometricPressure<br />&nbsp; &nbsp; &nbsp; <br />&nbsp; &nbsp; &nbsp; REAL(kind=C_DOUBLE), DIMENSION(7), INTENT(OUT)&nbsp; &nbsp;:: PropertyArray</p><p>&nbsp; END SUBROUTINE<br />&nbsp; <br />END INTERFACE</p><p>&nbsp; &nbsp; REAL :: TempDB_Test<br />&nbsp; &nbsp; REAL :: TempRH_Test<br />&nbsp; &nbsp; REAL :: BaroPressure<br />&nbsp; &nbsp; REAL(kind=C_DOUBLE), DIMENSION(7)&nbsp; &nbsp;:: PropertyArray</p><p>&nbsp; &nbsp; &nbsp; TempDB_Test = 308.15<br />&nbsp; &nbsp; &nbsp; TempRH_Test = 0.69<br />&nbsp; &nbsp; &nbsp; BaroPressure = 101.325<br />&nbsp; &nbsp; &nbsp; <br />&nbsp; &nbsp; &nbsp; CALL CalcAirProperties(2, TempDB_Test,TempRH_Test,BaroPressure,PropertyArray)<br />&nbsp; &nbsp; &nbsp; <br />&nbsp; &nbsp; &nbsp; RHiC = PropertyArray(3)<br />&nbsp; &nbsp; &nbsp; RhoAiC = PropertyArray(7)</p><p>END ProgramMain</p><p>!********************</p><p>The above method also did not work. So I am kind of lost. I am still a newbie when it comes to mixed language programming.</p><p>I understand this could not be a problem with Simply Fortran&nbsp; IDE, but I would appreciate any help in this matter from the FORTRAN experts in this forum.</p><p>p.s: Do not ind the array element noted by normal parenthesis instead of square parenthesis. The forum would not accept square parenthesis.</p>]]></content>
			<author>
				<name><![CDATA[sankarnkp]]></name>
				<uri>https://forums.approximatrix.com/profile.php?id=3473</uri>
			</author>
			<updated>2013-08-29T18:08:40Z</updated>
			<id>https://forums.approximatrix.com/viewtopic.php?pid=956#p956</id>
		</entry>
</feed>
