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

Linking FORTRAN/C

ambthiru
Beginner
385 Views

I am pretty new to FORTRAN and mixed language programming. I have this C programwith "main" function (and other functions inone .cfile)which when run outputs data into a .txt file. I need to call this C program from a FORTRAN code. I figured that you will have to use "INTERFACE" in the FORTRAN code for that. So when I create a dll of the C code and write $DEC! .... in my FORTRAN program and try to build the .exe file using CVF I get the following errors.

1. LNK 2001 - unresolved external symbol
2. LNK 1120 - unresolved externals

Pleaselet me knowhow to go about accomplishing the above.


0 Kudos
4 Replies
anthonyrichards
New Contributor III
385 Views

Before you can hope to get help, you need to post your C-code, in particular the lines showing your function prototype(s). You also need to show what Fortran code you have written. You also need to read the 'mixed language programming' sections of the Fortran user manual.

Since you are creating a DLL from the C-code, you will be EXPORTing symbols into a .LIB file which has to be included withthe Fortran project, which will also have toinclude relevant IMPORT directives before you stand a chance of getting the Fortran code to 'find' the DLL functions during LINKing stage.

See also the recent thread 'Linking C/Fortran' http://softwareforums.intel.com/en-us/forums//topic/51516

0 Kudos
ambthiru
Beginner
385 Views

The C code looks somewhatlike the one below

#include

#include

#include

void

UserInput(char *input,char *output);

void

NSIMain(int argc,char **argv)

{

char sInput[1024] = " ";

char sOutput[1024] = " ";

if

(argc>1)

{

printf(

"/n",*sInput);

printf(

"/n ",*sOutput);

}

else

{

UserInput(sInput,sOutput);

}

}

void main(int argc,char **argv)

{

NSIMain(argc,argv);

}

void

UserInput(char *input,char *output)

{

// Reads in the name of the profile file

printf(

" Enter the name of the file to be opened ");

scanf(

"%s",input);

// Reads in the name of the file where it will write the output

printf(

" Enter the name of the output file ");

scanf(

"%s",output);

}

I have compiled this code into a dll and had put the dll in the Debug folder of CVF. In my FORTRAN code I added the following code,

INTERFACE
SUBROUTINE NSIC()

!DEC$ ATTRIBUTES STDCALL,REFERENCE,ALIAS:"NSIC" :: NSIC

END SUBROUTINE
END INTERFACE

And called the SUBROUTINE NSIC. But CVF is not able to find the C dll. Please let me know how I can do away with this problem.

0 Kudos
anthonyrichards
New Contributor III
385 Views

Where is your dllmain function? Where are your dllexport qualifiers? Where and what is NSIC?

Why not try to walk before you try to run and write C-code containing all your functions and routines that you want to be in your library. Then identify which functions/routines you want to be directly callable from Fortran.

Make the latter 'external __cdecl(dllexport) void UserFunction( int *arg1, int *arg2)' onthe C side [integer arguments chosen purely for illustration].

The 'external' will prevent name-mangling and the '__cdecl(dllexport)' will create exportable symbols in the DLL of the type '_UserFunction' (for a C-function named 'UserFunction'). Remember C preserves case, so on the Fortran side, make sure your ALIAS matches the case of the C-function EXACTLY and includes the leading underscore.

A dll should not contain a 'main' I think, as it is not an executable as such. If you use the project wizard to create a win32 dll [called, for example dllname.dll], it will create a template for you to which you can add your prototypes and function definitions. The wizard will supply a standard'dllmain' function. When you build your Dll, the presence of the 'dllexport' qualifiers should cause the parallel creation of a dllname.dll and a dllname.lib file. The dllname.lib file must then be added to the Fortran project containing the Fortran main program that calls the C dll. which shouldautomatically contain the WinMain function that Windows needs to call to start the executable. In the Fortran, for each C- function or routine (C-void function) that you want to call, you must supply an INTERFACE block along the lines you have written but it must contain also a DLLIMPORT directive so that the compiler knows that the symbol defined in your ALIAS directive should be searched for in an external module. The ATTRIBUTES directive should contain C,REFERENCE (to match the __cdecl on the C side) and each argument should be specified with its appropriate attribute directive, i.e. by REFERENCE or by VALUE, depending on what you have on the C-side [value or pointer(*) ]. I would recommend using pointers on the C-side for everything, so that all your arguments should be given the REFERENCE attribute on the Fortran side. This can avoid problems with C-string hidden length arguments.

Read the'mixed language programming' chapter of themanual again, and again.

0 Kudos
ambthiru
Beginner
385 Views
Got the problem resolved. Thank You! When I had to get the work done, had to compromise on learning :)
0 Kudos
Reply