using C++ classes in a third-party shared library
843829Jun 18 2009 — edited Jun 18 2009Would be very grateful if someone could help me out with the following problem that I am having (apologies if this has been answered elsewhere but I have been searching the web for ages and can't find a solution )
I have a requirement for a java app to access a C++ class in a third party shared library. To test my solution and illustrate the problem I have developed the following test code.
I am developing on SUSE 11.1 using Suns Java 1.5 and g++ 4.3.2
$LD_LIBRARY_PATH = /home/raughterd/projects/dpa/jnitest:/usr/lib/mpi/gcc/openmpi/lib
First developed a test class library libfred.so
fred.h
#ifndef __FRED_H__
#define __FRED_H__
class fred
{
public:
void test() const;
};
#endif // __FRED_H__
fred.cc
#include <iostream>
#include "fred.h"
void fred::test() const
{
std::cout << "Called fred.test" << std::endl;
}
built it with the following
g++ -c -Wall -I. fred.cc
g++ -shared fred.o -o libfred.so
Then developed java test application Tester
jnitest.java
class jnitest
{
static
{
System.loadLibrary("jnitest");
}
public native void test();
}
Tester.java
class Tester
{
public static void main(String[] args)
{
jnitest x = new jnitest();
x.test();
}
}
both compiled with
javac xxxxx.java
and developed libjnitest.so by
javah -jni jnitest
to produce jnitest.h
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class jnitest */
#ifndef Includedjnitest
#define Includedjnitest
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: jnitest
* Method: test
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_jnitest_test
(JNIEnv *, jobject);
#ifdef __cplusplus
}
#endif
#endif
wrote jnitestimpl.cc
#include <iostream>
#include "jnitest.h"
#include "fred.h"
JNIEXPORT void JNICALL
Java_jnitest_test(JNIEnv *, jobject)
{
std::cout << "called C++ func" << std::endl;
fred afred;
afred.test();
}
compiled with
g++ -c -Wall -I. jnitestimpl.cc
g++ -shared jnitestimpl.o -o libjnitest.so
ran the test application
java Tester
which produced
Exception in thread "main" java.lang.UnsatisfiedLinkError: /home/raughterd/projects/dpa/jnitest/libjnitest.so: /home/raughterd/projects/dpa/jnitest/libjnitest.so: undefined symbol: _ZNK4fred4testEv
at java.lang.ClassLoader$NativeLibrary.load(Native Method)
at java.lang.ClassLoader.loadLibrary0(ClassLoader.java:1751)
at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1676)
at java.lang.Runtime.loadLibrary0(Runtime.java:822)
at java.lang.System.loadLibrary(System.java:993)
at jnitest.<clinit>(jnitest.java:5)
at Tester.main(Tester.java:5)
Without the references to the fred class in jnitestimpl.cc everything works fine. It is only when I try to use the fred class in the jnitestimpl.cc that I get the exception. I am guessing that it is something to do with the name mangling and maybe compiler options but that is just a guess. ( libfred.so and libjnitest.so are in the current directory which is on the LD_LIBRARY_PATH )
Any ideas? Any help would be greatly appreciated
Many thanks