F
FBergemann
Hi all,
I try to load a C++ shared library for executing a main-driver for
send/receive of messages, which (the main-driver) calls JAVA again to
do the real work for processing the message (both via JNI).
I assume, that there could be a couple of more pitfalls to this
approach - but i get already problems to start the proper module:
I get following error message, when starting the JAVA MainWrapper
class:
exception in thread "main" java.lang.UnsatisfiedLinkError:
<...>/run/lib/libBSproxy.so.1.0: ld.so.1: /usr/j2se/bin/sparcv9/java:
fatal: relocation error: file <...>/run/lib/libBSproxy.so.1.0: symbol
_ZNSs4_Rep11_S_terminalE: referenced symbol not found
at java.lang.ClassLoader$NativeLibrary.load(Native Method)
at java.lang.ClassLoader.loadLibrary0(ClassLoader.java:1473)
at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1397)
at java.lang.Runtime.loadLibrary0(Runtime.java:788)
at java.lang.System.loadLibrary(System.java:832)
at MainWrapper.<clinit>(BSproxy.java:18)
JAVA:
=====
// do the real work per message here:
class Process {
public static void doit(String msg) {
System.out.println("[Process::doit: " + msg + "]");
}
}
// invoke the C++ main loop here:
class MainWrapper {
public native int loop();
public String message_data;
static {
System.out.println("load shared libraries...");
System.out.println("->BSproxy");
System.loadLibrary("BSproxy");
System.out.println("...done");
}
// embed a main() here as static to start once for this class
public static void main(String[] args) {
MainWrapper main_wrapper = new MainWrapper();
int status = main_wrapper.loop();
}
}
C++:
====
#include <iostream>
#include <jni.h>
// JNI stuff
#include "BSproxy_loop.h"
static JNIEnv *my_jni_env_glb = 0L;
class MyServer: private ComLayer::Server
{
public:
MyServer(const std::string& cfg, const std::string& name):
shutdown(this) {
new ComLayer::Listener(this, new
ComTransport::TcpService(cfg, name, 1));
cnt=0;
}
void AttachConnection(ComLayer::Connection *con)
{ ...
}
void DetachConnection(ComLayer::Connection *con)
{ ...
}
// callback function for
// 1. receiving a message,
// 2. process it and
// 3. return the response
void MsgReady(ComLayer::Connection *con)
{ std::string input;
std::string output;
con->GetMsg(input);
// now call JAVA again to process the msg
// --------------------------------------
jclass processing_cls =
my_jni_env_glb->FindClass("Processing");
jmethodID doit_f =
my_jni_env_glb->GetStaticMethodID(processing_cls, "doit",
"(Ljava/lang/String
V");
// jump to JAVA processing
// stat = ProcessJava(input, output)
output = input;
con->PutMsg(output);
}
};
JNIEXPORT jint JNICALL
Java_MainWrapper_loop(JNIEnv *env, jobject obj) {
char *name="BSproxy";
char *cfg="BSproxy.cfg";
int c;
my_jni_env_glb = env;
std::cout << "test\n";
MyServer server(cfg, name);
// this method won't return to JAVA
// but MsgReady is called and invokes JAVA again
// internal function of the C++ lib
ProcessEvents();
return (jint)0;
}
The purpose of the whole story is to re-use the C++ main driver (for
message communication protocol) as is.
I know, the _ZNSs4_Rep11_S_terminalE comes from g++ include file
<...>/gcc-3.3.5/include/bits/basic_string.h
But i don't get it compiled into the shared library libBSproxy.so
And i can't find a shared library, which holds it (but to be honest we
don't have installed liststdc++.so - only the static one).
Do i necessarily need the dynamic lib liststdc++.so?
Or is there any other work-around?
- Many Thanks!
Regards!
Frank
I try to load a C++ shared library for executing a main-driver for
send/receive of messages, which (the main-driver) calls JAVA again to
do the real work for processing the message (both via JNI).
I assume, that there could be a couple of more pitfalls to this
approach - but i get already problems to start the proper module:
I get following error message, when starting the JAVA MainWrapper
class:
exception in thread "main" java.lang.UnsatisfiedLinkError:
<...>/run/lib/libBSproxy.so.1.0: ld.so.1: /usr/j2se/bin/sparcv9/java:
fatal: relocation error: file <...>/run/lib/libBSproxy.so.1.0: symbol
_ZNSs4_Rep11_S_terminalE: referenced symbol not found
at java.lang.ClassLoader$NativeLibrary.load(Native Method)
at java.lang.ClassLoader.loadLibrary0(ClassLoader.java:1473)
at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1397)
at java.lang.Runtime.loadLibrary0(Runtime.java:788)
at java.lang.System.loadLibrary(System.java:832)
at MainWrapper.<clinit>(BSproxy.java:18)
JAVA:
=====
// do the real work per message here:
class Process {
public static void doit(String msg) {
System.out.println("[Process::doit: " + msg + "]");
}
}
// invoke the C++ main loop here:
class MainWrapper {
public native int loop();
public String message_data;
static {
System.out.println("load shared libraries...");
System.out.println("->BSproxy");
System.loadLibrary("BSproxy");
System.out.println("...done");
}
// embed a main() here as static to start once for this class
public static void main(String[] args) {
MainWrapper main_wrapper = new MainWrapper();
int status = main_wrapper.loop();
}
}
C++:
====
#include <iostream>
#include <jni.h>
// JNI stuff
#include "BSproxy_loop.h"
static JNIEnv *my_jni_env_glb = 0L;
class MyServer: private ComLayer::Server
{
public:
MyServer(const std::string& cfg, const std::string& name):
shutdown(this) {
new ComLayer::Listener(this, new
ComTransport::TcpService(cfg, name, 1));
cnt=0;
}
void AttachConnection(ComLayer::Connection *con)
{ ...
}
void DetachConnection(ComLayer::Connection *con)
{ ...
}
// callback function for
// 1. receiving a message,
// 2. process it and
// 3. return the response
void MsgReady(ComLayer::Connection *con)
{ std::string input;
std::string output;
con->GetMsg(input);
// now call JAVA again to process the msg
// --------------------------------------
jclass processing_cls =
my_jni_env_glb->FindClass("Processing");
jmethodID doit_f =
my_jni_env_glb->GetStaticMethodID(processing_cls, "doit",
"(Ljava/lang/String
// jump to JAVA processing
// stat = ProcessJava(input, output)
output = input;
con->PutMsg(output);
}
};
JNIEXPORT jint JNICALL
Java_MainWrapper_loop(JNIEnv *env, jobject obj) {
char *name="BSproxy";
char *cfg="BSproxy.cfg";
int c;
my_jni_env_glb = env;
std::cout << "test\n";
MyServer server(cfg, name);
// this method won't return to JAVA
// but MsgReady is called and invokes JAVA again
// internal function of the C++ lib
ProcessEvents();
return (jint)0;
}
The purpose of the whole story is to re-use the C++ main driver (for
message communication protocol) as is.
I know, the _ZNSs4_Rep11_S_terminalE comes from g++ include file
<...>/gcc-3.3.5/include/bits/basic_string.h
But i don't get it compiled into the shared library libBSproxy.so
And i can't find a shared library, which holds it (but to be honest we
don't have installed liststdc++.so - only the static one).
Do i necessarily need the dynamic lib liststdc++.so?
Or is there any other work-around?
- Many Thanks!
Regards!
Frank