- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi! I created a Fortran code with 3 function. This is my Fortran code:
real function circle_area(radius)
!DEC$ ATTRIBUTES DLLEXPORT :: CIRCLE_AREA
!DEC$ ATTRIBUTES ALIAS : "Circle_Area" :: CIRCLE_AREA
implicit none
real radius
real, parameter :: PI = 3.14159
circle_area = radius*radius*PI
return
end function
integer function sum(a)
!DEC$ ATTRIBUTES DLLEXPORT :: SUM
implicit none
integer :: a(10)
integer i
sum=0
do i=1,10
sum=sum+a(i)
end do
return
end function
subroutine MakeLower(string)
!DEC$ ATTRIBUTES DLLEXPORT :: MAKELOWER
implicit none
character(len=*) :: string
integer :: len, i, code
len = len_trim(string)
do i=1,len
code = ichar(string(i:i))
if ( code >= ichar('a') .and. code <= ichar('z') ) then
string(i:i) = char(code-32)
end if
end do
return
end subroutine
I use this Fortran code to create dll (Dll1). Then I wrote a c program to call function circle_area() in Fortran code.
#include "stdafx.h"
#include "stdlib.h"
extern "C" {float circle_area(float *a); }
int _tmain(int argc, _TCHAR* argv[])
{
float b = 3.;
circle_area(&b);
system("pause");
return 0;
}
Before I ran my c code, I included my dll in Visual Studio 2013. First I added my Dll1.lib directory in VC++ directories-> Library Directories, in Linker -> General -> Additional Library Directories added Dll1.lib directory again, in Linker -> Input -> Additional Dependencies added Dll1.lib. Last, I put Dll1.dll in c project folder that it will create .exe together.
After running my c code, I got these messages :
error LNK2019: unresolved external symbol '_circle_area ' referenced in function '_wmain'
error LNK1120: 1 unresolved external symbol
It seems that I need something setup. Can someone help me?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
You may also want to keep in mind the standard option:
module m use, intrinsic :: iso_c_binding, only : c_float implicit none private public :: circle_area real(c_float), parameter :: PI = 3.14159 !.. Is this precise enough for your needs? ! pi = acos(-1.0_xx) is one way to get most precision ! for a selected real kind of xx contains function circle_area(radius) result( Area ) bind(C, name="Circle_Area") !DEC$ ATTRIBUTES DLLEXPORT :: CIRCLE_AREA real(c_float), intent(in), value :: radius !.. Function result real(c_float) :: Area Area = PI*radius*radius return end function circle_area end module m
#include <iostream> using namespace std; extern "C" { // Prototype for the Fortran Function float Circle_Area( float ); } int main() { float r = 2.0; cout << "Area of circle with radius of 2.0 = " << Circle_Area(r) << endl; return 0; }
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Add "DECORATE," before ALIAS. You told Fortran that the external name was just "Circle_Area" but C, on 32-bit WIndows, adds a leading underscore (as does Fortran for normal use.) DECORATE tells Fortran to add the appropriate platform-specific name decoration.
You don't put dll.lib in "Additional library directories". Instead you put the directory where dll.lib is put. Note also that you will need to copy the DLL itself to the executable directory.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
You may also want to keep in mind the standard option:
module m use, intrinsic :: iso_c_binding, only : c_float implicit none private public :: circle_area real(c_float), parameter :: PI = 3.14159 !.. Is this precise enough for your needs? ! pi = acos(-1.0_xx) is one way to get most precision ! for a selected real kind of xx contains function circle_area(radius) result( Area ) bind(C, name="Circle_Area") !DEC$ ATTRIBUTES DLLEXPORT :: CIRCLE_AREA real(c_float), intent(in), value :: radius !.. Function result real(c_float) :: Area Area = PI*radius*radius return end function circle_area end module m
#include <iostream> using namespace std; extern "C" { // Prototype for the Fortran Function float Circle_Area( float ); } int main() { float r = 2.0; cout << "Area of circle with radius of 2.0 = " << Circle_Area(r) << endl; return 0; }
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Steve Lionel (Intel) wrote:
Add "DECORATE," before ALIAS. You told Fortran that the external name was just "Circle_Area" but C, on 32-bit WIndows, adds a leading underscore (as does Fortran for normal use.) DECORATE tells Fortran to add the appropriate platform-specific name decoration.
You don't put dll.lib in "Additional library directories". Instead you put the directory where dll.lib is put. Note also that you will need to copy the DLL itself to the executable directory.
"You don't put dll.lib in "Additional library directories".", I don't understand! Don't I add Dll1.lib directory in "Additional library directories"?
Does "copy the DLL" means copy the Dll1.dll only?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
You put the directory containing dll1.lib there, not "dll1.lib".
Yes, copy the .dll only.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thanks for your help! I referenced you comments,then adjusted my code!
I am so happy that my program works now! But I have a big Fortran function called in C++.
So I need to adjust Fortran function simply.
And is there any document or what I can read about using C++ call Fortran dll ?
#include "stdafx.h" #include <iostream> using namespace std; extern "C" {float CIRCLE_AREA(float *a ); } int _tmain(int argc, _TCHAR* argv[]) { float r = 2.; cout << "Area of circle with radius of 2.0 = " << CIRCLE_AREA(&r) << endl; system("pause"); return 0; }
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
There is a full chapter, "Mixed Language Programming", in the Intel Fortran Compiler Reference.
You may not find much about calling Fortran directly in C++. The Fortran standard specifies interoperability with C, not with C++. However, the extern "C" {...} construct of C++ takes care of this.
[Corrected by adding quotes, as stated in #8]
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
That's:
extern "C"
You need the quotes.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Okay! I see. Thanks!
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page