[zeromq-dev] Is there a way to safely read a string from Java given a C (char *) using Java? (Monitoring ZeroMQ sockets in Java)
Chinmay
nchinmay at hotmail.com
Thu Apr 25 15:58:42 CEST 2013
I am using JZMQ wrapper for ZeroMQ 3.2.3 and in a thread I have the need to
detect `ZMQ_EVENT_ACCEPTED` and `ZMQ_EVENT_DISCONNECTED` events. The ZeroMQ
C library has the function `int zmq_socket_monitor (void *socket, char *
*addr, int events);` as detailed by
http://api.zeromq.org/3-2:zmq-socket-monitor. The events are returned to my
application on a separate receiving `PAIR` socket as detailed by the above link.
JZMQ however does not have a binding for the above function. So I tried
making one.
/**
* Called by Java's Socket::monitorSocket(String inProcAddr, int events).
*/
JNIEXPORT jint JNICALL Java_org_zeromq_ZMQ_00024Socket_monitorSocket
(JNIEnv *env,
jobject obj,
jstring addr,
jint events)
{
#if ZMQ_VERSION >= ZMQ_MAKE_VERSION(3,2,2)
void *s = get_socket (env, obj);
if (addr == NULL) {
raise_exception (env, EINVAL);
return -1;
}
const char *c_addr = env->GetStringUTFChars (addr, NULL);
if (c_addr == NULL) {
raise_exception (env, EINVAL);
return -1;
}
int rc = zmq_socket_monitor (s, c_addr, events);
int err = zmq_errno();
env->ReleaseStringUTFChars (addr, c_addr);
if (rc != 0) {
raise_exception (env, err);
}
return rc;
#else
return -1;
#endif
}
Now my receiving `PAIR` socket in java will receive a message for events
which will have structure as per the C struct (as per zmq.h)
/* Socket event data (union member per event)
*/
typedef struct {
int event;
union {
struct {
char *addr;
int fd;
} connected;
struct {
char *addr;
int err;
} connect_delayed;
struct {
char *addr;
int interval;
} connect_retried;
struct {
char *addr;
int fd;
} listening;
struct {
char *addr;
int err;
} bind_failed;
struct {
char *addr;
int fd;
} accepted;
struct {
char *addr;
int err;
} accept_failed;
struct {
char *addr;
int fd;
} closed;
struct {
char *addr;
int err;
} close_failed;
struct {
char *addr;
int fd;
} disconnected;
} data;
} zmq_event_t;
Since I will get this data in Java, can I assume on a 64 bit machine, the
first 8 bytes correspond to the `char *addr` and the remaining 8 byte `int`
is the fd/err/interval? More importantly is there a way to get the string
corresponding safely to this `char *addr`, possibly by making another java
function to make a JNI call that returns a `jstring`? By 'safely' I mean
calling with a wrong pointer value I don't want to crash the system.
More information about the zeromq-dev
mailing list