- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I'm trying to connect Java to intel visual fortran using JNI. One of the steps in the way is to create a dll library that contains visual fortran files and c++ files.
Do you know how to build a dll library that contains visual fortran files and C++ (or visual c++)files?
Thank you.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
On the C++ simply declare the function as:
[cpp]extern "C" void fortprinthello();[/cpp]
Then, on the fortran side add the bind suffix to the subroutine call. The bind NAME= argument needs to match (case sensitive) the C++ declaration of the function, your fortran subroutine name can then be whatever you want (alternatively, without a NAME= specifier the C++ side wants a lower case version of the fortran name).
[plain]subroutine WhateverYouWant() bind(C, NAME='fortprinthello') print *, 'Hello World' end subroutine [/plain]
Getting the Fortran and C++ symbol names and calling convention to match up is then the compiler's problem, not yours.
The dynamic library suggestion relates to dynamically linking to the the C and fortran runtime libraries. This can avoid problems with "multiple runtime library syndrome" down the track, which has been known to cause premature aging. Add /MD to both command lines. To get ifort to actually build a DLL you'll also need the /dll option on its command line.
Good luck.
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Do you know how to build a dll library that contains visual fortran files and C++ (or visual c++)files?
USE iso_c_interop and the corresponding data types. In my limited Windows experience, using Fortran to create the .dll should automatically refer to all necessary basic libraries, with dynamic linking probably being easier.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
USE iso_c_interop and the corresponding data types. In my limited Windows experience, using Fortran to create the .dll should automatically refer to all necessary basic libraries, with dynamic linking probably being easier.
I don't exactly understand your answer. But, let me give you a more detailed scenario:
1- I have the following C++ file CCode.cpp
#include
#include "JavaCode.h"
extern "C" void __stdcall fortprinthello();
JNIEXPORT void JNICALL Java_JavaCode_printhello(JNIEnv *env,jobject obj)
{
fortprinthello();
}
2- I have the following fortran 90 program (FortranCode.f90)
subroutine fortprinthello()
print *, 'Hello World'
end subroutine
I'm trying to compile and link those 2 programs together using visual studio command line and intel visual fortran command line. So, what I'm doing is the following:
a- Compile cpp file using visual studio command line compiler:
cl -I"c:Program FilesJavajdk1.6.0_14include" -I"c:Program FilesJavajdk1.6.0_14includewin32" /c CCode.cpp
b- This works and generates CCode.obj, then I execute this command using intel visual fortran compiler
ifort CCode.obj FortranCode.f90
I get the following error:
CCode.obj : error LNK2019: unresolved external symbol _fortprinthello@0 referenced in function _Java_JavaCode_printhello@8
Any idea what is happening?
Thank you
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
On the C++ simply declare the function as:
[cpp]extern "C" void fortprinthello();[/cpp]
Then, on the fortran side add the bind suffix to the subroutine call. The bind NAME= argument needs to match (case sensitive) the C++ declaration of the function, your fortran subroutine name can then be whatever you want (alternatively, without a NAME= specifier the C++ side wants a lower case version of the fortran name).
[plain]subroutine WhateverYouWant() bind(C, NAME='fortprinthello') print *, 'Hello World' end subroutine [/plain]
Getting the Fortran and C++ symbol names and calling convention to match up is then the compiler's problem, not yours.
The dynamic library suggestion relates to dynamically linking to the the C and fortran runtime libraries. This can avoid problems with "multiple runtime library syndrome" down the track, which has been known to cause premature aging. Add /MD to both command lines. To get ifort to actually build a DLL you'll also need the /dll option on its command line.
Good luck.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
On the C++ simply declare the function as:
[cpp]extern "C" void fortprinthello();[/cpp]
Then, on the fortran side add the bind suffix to the subroutine call. The bind NAME= argument needs to match (case sensitive) the C++ declaration of the function, your fortran subroutine name can then be whatever you want (alternatively, without a NAME= specifier the C++ side wants a lower case version of the fortran name).
[plain]subroutine WhateverYouWant() bind(C, NAME='fortprinthello') print *, 'Hello World' end subroutine [/plain]
Getting the Fortran and C++ symbol names and calling convention to match up is then the compiler's problem, not yours.
The dynamic library suggestion relates to dynamically linking to the the C and fortran runtime libraries. This can avoid problems with "multiple runtime library syndrome" down the track, which has been known to cause premature aging. Add /MD to both command lines. To get ifort to actually build a DLL you'll also need the /dll option on its command line.
Good luck.
Thank you Tim and Ian, your comments are really useful. Just for the benefit of everyone, I will list all the files and command I used:
1- The general problem is: create a java program that uses JNI to invoke fortran method through C++ given that the following compilers will be used:
* Intel Visual Fortran command line compiler
* Visual C++ command line compiler
* javac java compiler
2- The complete solution (Thanks to Tim and Ian) is the following:
Java File (JavaCode.java):
----------------------------------
class JavaCode
{
private native void printhello();
public static void main(String[] args)
{
new JavaCode().printhello();
}
static
{
try
{
System.out.println("java.library.path="+System.getProperty("java.library.path"));
System.loadLibrary("HelloWorld");
}
catch(Exception x)
{
System.out.println("exception loading library");
x.printStackTrace();
}
}
}
--------------------------------------------
I compile it using: javac JavaCode.java
The result is JavaCode.class
Next, I use javah to generate C++ header file as follows javah -jni JavaCode
The result is the following file JavaCode.h
-----------------------------------------------
JavaCode.h
-----------------------------------------------
/* DO NOT EDIT THIS FILE - it is machine generated */
#include
/* Header for class JavaCode */
#ifndef _Included_JavaCode
#define _Included_JavaCode
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: JavaCode
* Method: printhello
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_JavaCode_printhello
(JNIEnv *, jobject);
#ifdef __cplusplus
}
#endif
#endif
------------------------------------------
Next I write my simple fortran file:
------------------------------------------
FortranCode.f90
------------------------------------------
subroutine fortprinthello() bind(C, NAME='fortprinthello')
print *, 'Hello World'
end subroutine
-----------------------------------------
Next I compile fortran code using intel visual fortran command line prompt
ifort /c FortranCode.f90
The result is FortranCode.obj
-----------------------------------------
Next I write the C++ file which implements method in JavaCode.h and calls fortran routine
-----------------------------------------
CCode.cpp
-----------------------------------------
#include
#include "JavaCode.h" // Required header for JNI
extern "C" void fortprinthello();
JNIEXPORT void JNICALL Java_JavaCode_printhello(JNIEnv *env,jobject obj) {
fortprinthello();
}
void main()
{
fortprinthello();
}
-------------------------------------------------------------------
Next I compile it using visual c++ command line
cl -I"c:Program FilesJavajdk1.6.0_14include" -I"c:Program FilesJavajdk1.6.0_14includewin32" -LD FortranCode.obj CCode.cpp -FeHelloWorld.dll
The result is CCode.obj and HelloWorld.dll
The last thing to do is to set the library path and run the java code
java -Djava.library.path=. JavaCode
I hope you find this information useful.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I'm trying to connect Java to intel visual fortran using JNI. One of the steps in the way is to create a dll library that contains visual fortran files and c++ files.
Do you know how to build a dll library that contains visual fortran files and C++ (or visual c++)files?
Thank you.
A few days ago I posted a tiny sample in how to do that:
http://software.intel.com/en-us/forums/showthread.php?t=67274
Veit
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I helped me a lot

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