Re: Calling a matlab dll in java



Hi,

all in all I managed to create a sample code that works (without
crashing JVM). So here goes what I did:
- first I wrote a simple function in matlab returnig a random value
after 3 second pause
- I compiled it with mcc to dll shared library
- using JNI (Java Native Interface) i created method to acces the dll
function
- finaly I managed to run it in JAVA

I launched several threads with this matlab function and... it worked
:) I mean running it multithreaded.

The only thing I was not able to do (and I think I need to ask
Mathwork's people about this one) is using Matlab's VM inside compiled
m-function. When initializing the dll library '-nojvm' option must be
set, otherwise it crashes the virtual machine!!! In my case that's a
serious issue :(

ok... so here are some exceptions from my code:

m-function 'myrand.m' looks like this:

<code>

% Returns random value after 3 seconds
function r = myrand()
pause(3);
r = rand();

</code>

then I use the compiler to generate the dll ('libmyrand.dll')

mcc -W cpplib:libmyrand -T link:lib -v myrand.m

then you create a cpp file that uses JNI to access the funcion (setting
all compiler and linker options in VS took me a while, as I am not very
used to it :/ ). Remeber to add all Matlab's and Java includes to
compiler path, and directories with .lib files to linker options. Oh...
and you need to compile it as dll of course.

<code>
// JNITest_JNITest.cpp : Defines the entry point for the console
application.

#include "stdafx.h"
#include <mclmcr.h>
#include "libmyrand.h"
#include "JNITest_JNITest.h"

#pragma comment (lib, "libmyrand.lib")
#pragma comment(lib, "mclmcr.lib")

using namespace std;

JNIEXPORT void JNICALL Java_JNITest_JNITest_initializeApplication
(JNIEnv *, jobject)
{
//initialize MATLAB application and initialize library
//IMPORTANT: set to nojvm otherwise you get jvm crash :(((
const char* ops = "-nojvm";
if ( !mclInitializeApplication(&ops,1) || !libmyrandInitialize() )
{
std::cerr << "could not initialize the library properly" <<
std::endl;
}
}

JNIEXPORT void JNICALL Java_JNITest_JNITest_terminateApplication
(JNIEnv *, jobject)
{
//terminate MATLAB application
libmyrandTerminate();
mclTerminateApplication();
}

JNIEXPORT jstring JNICALL Java_JNITest_JNITest_getHello
(JNIEnv * env, jobject)
{
//perform operation using library functions
mwArray w;
myrand(1, w);

//compose result string
std::string s = "hello: ";
s.append( w.ToString() );

return env->NewStringUTF( s.c_str() );
}
</code>

finaly you need to copy the dll's (in my case libmyrand.dll and
libjnitest.dll) and ctf (generated while compiling, i.e. libmyrand.ctf)
to you java project and write simple code to test it (JNITest.java):
<code>
package JNITest;

import java.io.*;

public class JNITest
{
native void initializeApplication();
native void terminateApplication();
native String getHello();

public void launchThread()
{
new Thread() {
public void run()
{
System.out.println( getHello() );
}
}.start();
}

public static void main( String[] args )
{
//load dynamic library with native methods
File lib = new File( new File(System.getProperty("user.dir") ),
"libjnitest.dll");
System.load( lib.getAbsolutePath() );

//start benchmark
System.out.println( "hello START");
double timestamp = System.nanoTime();

//evoke native call
JNITest t = new JNITest();
t.initializeApplication();

System.out.println( t.getHello() );
System.out.println( t.getHello() );
System.out.println( t.getHello() );
System.out.println( t.getHello() );
System.out.println( t.getHello() );


t.terminateApplication();
//stop benchmark
timestamp = (System.nanoTime()-timestamp)/1e6;
System.out.println( "hello STOP in " + timestamp + "[ms]");
}
}
</code>

ok... sorry for a long response, but after hours of searching I could
not find step-by-step 'how to' :(

hope this will help :)

Cheers :)

Wojciech Gradkowski

.



Relevant Pages

  • Re: Calling a matlab dll in java
    ... you mention about putting a -nojvm option when initializing the dll ... the matlab generated library inside my jni-dll) ... all compiler and linker options in VS took me a while, ... JNIEXPORT void JNICALL ...
    (comp.soft-sys.matlab)
  • Re: Calling a matlab dll in java
    ... you mention about putting a -nojvm option when initializing the dll ... When initializing the dll library '-nojvm' option must ... all compiler and linker options in VS took me a while, ... JNIEXPORT void JNICALL Java_JNITest_JNITest_initializeApplication ...
    (comp.soft-sys.matlab)
  • Re: fields for methods?
    ... void A::foo{ ... but only by a compiler that is allowed to ... int static_instance i = 0; ... it totally breaks the idea of encapsulation, which is the reason a lot ...
    (comp.programming)
  • Re: Exposing bool to non-MS, non-C++ callers
    ... the functions in this DLL accept a structure as an argument. ... The compiler doesn't help catch places where I neglect ... the C++ bool type is defined as one byte. ... depends on whether the Exe caller will push a value larger than 1 byte. ...
    (microsoft.public.dotnet.languages.vc)
  • Re: fields for methods?
    ... but only by a compiler that is allowed to ... struct A {void foo();}; ... int static_instance i = 0; ... Is not possible because foo is the only member of A... ...
    (comp.programming)