- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hello,
I have a big problem. I want to call a routine in Java from Fortran dll. I have the wrapper c++ that let me conect with fortran, but when I try to compile the dll with the wrapper in c++ and the fortran code I obtain some link errors, for example, it does't find the symbol netcal. Should I compile the two codes together?? How I must compile it? I use compaq visual. I show you the simply code that I have.
the file in c++ is:
#include
#include "clase.h"
extern "C" void netcal(long*a, long*b, long*c);
JNIEXPORT void JNICALL Java_clase_netcal
(JNIEnv *, jobject, jint a, jint b, jint c)
{
netcal(&a, &b, &c);
};
and the code in fortran is:
subroutine netcal(a,b,c)
integer, target, intent(in)::a,b
integer, target, intent(out)::c
c=a+b
return
end subroutine netcal
Thank you very much!!
Jara
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
[fortran]subroutine netcal(a,b,c) bind(C, name="netcal") integer, target, intent(in)::a,b integer, target, intent(out)::c c=a+b end subroutine netcal[/fortran]
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
You may already have noticed that you won't recieve the value written to out param c to Java the way you are calling it.
As Java does not have out parameters, you need to e.g. use a size 1 int array, something like this:
JNIEXPORT void JNICALL Java_clase_netcal
(JNIEnv *env, jobject, jint a, jint b, jintArray c)
{
long cval ;
netcal(&a, &b, &cval);
(*env)->SetIntArrayRegion( env, c, 0, 1, &cval ) ;
}
Corresponding method in class clase:
native void netcal( int a, int b, int[] c ) ;
If you have more functions you must access from Java, I highly recommend to use swig (www.swig.org) to generate the jni glue for you.
Also note that if you do not use extern(c) in your fortran routine, you will have to (at least on windows) include the appropriate calling convention to the c prototype of the func (__stdcall on windows). I think extern(c) automatically uses the appropriate calling convention to interoperate with c (i.e. __cdecl). Note, however, that if you call the same (Fortran) routine from your Fortran code, you need to use explicit interfaces (e.g. have your code in a module) as otherwise the calling Fortran code will use the wrong calling convention ( on windows __stdcall when the called function is using __cdecl) and this will mess up your stack.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
No, stdcall is not "default" for Windows (it is for Win32 API, but that's entirely different context). Intel Fortran uses __cdecl by default, and BIND(C) attribute is designed to pick up the right calling convention (the one used by the "companion C processor") in any case.
- 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
I must have expressed myself badly. I meant cdecl is the default for c compilers as you said.
But I seem to have been wrong about stdcall being the default for ifort compiled routines - it is indeed cdecl. We are using /Gm compiler option which changes it to stdcall. I stand corrected.

- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page