Reputation: 125
I have used a method in a reference book about fortran codes calling c codes. The method is that if your function name in the c codes are capitalized, you may not make additional changes in your fortran code. The following is my code.
Source1.f90:
program main
implicit none
call c_subprint()
endprogram
ccode.c:
#include <stdio.h>
#include <string.h>
#ifdef _cplusplus
extern "C" {
#endif
void _stdcall C_SUBPRINT()
{
int a;
printf("%s\n","kk");
scanf("%d",&a);
}
#ifdef _cplusplus
}
#endif
The error message is that the main function cannot find out _C_SUBPRINT(LNK2019). But I have already added the .lib generated by the c code to the fortran code. And my code is almost the same as that in the reference book. what is wrong?
Upvotes: 0
Views: 156
Reputation: 46365
From the inclusion of _stdcall
I deduce you are probably using a Windows platform. Unfortunately I'm working on a Mac, so things may not be exactly the same. However, the following works for me (small changes from your code) to get a mix of Fortran and C code working together. Note - on my Mac, the gcc
compiler does not include Fortran, so I used a separate Fortran compiler gfortran
which I downloaded from a link at http://hpc.sourceforge.net - where instructions for installation could also be found.
program src1.f90:
program main
implicit none
call C_SUBPRINT()
endprogram
program ccode.c:
#include <stdio.h>
#include <string.h>
void c_subprint_()
{
printf("hello world!\n");
}
Note I took out the #ifdef
sections - I was using pure C, so it was not needed; more importantly, note the underscore after the function name
I compiled these two modules as follows:
gcc -c ccode.c -o ccode.o
gfortran src1.f90 ccode.o -o hello
After which I can run
./hello
And get the expected output:
hello world!
Without the underscore, the linker complains about unknown symbols. There is an option in the compiler to turn off "name mangling" with the underscore. You can check your specific compiler to see how that would be done - but that's almost certainly the problem you are having.
Upvotes: 1
Reputation: 29391
Different Fortran compilers generate calls differently. Many add underscores to routine names to avoid name conflicts with C-code. Its very hard to say whether or not you should exactly follow the example of an unnamed reference book. In the past, to mix Fortran and C, you have to understand some of the compiler internals. Here the Fortran compiler appears to have added an underscore to the start of the name. You could probably fix the problem by adding that in your C++ code. But that won't be portable and in principle could change with compiler versions. There is a better way: the Fortran ISO_C_Binding. This is part of the Fortran language standard and therefore standard and portable. Examples are given in the gfortran manual in the Chapter "Mixed-Language Programming" and in other questions on Stackoverflow.
Upvotes: 2