Accessing global variables in native C code when calling from Java
Hi, I wonder if you can help me please.
I'm calling the below function testBloom() from Java. In function test2(), the value of foo() is not 5, it's always some random huge number like 3432134 or -23278237. If I replace foo inside test2() with a literal value, all works fine as expected. This implies to me there's a problem accessing global variables in native C code when calling from JNI. Can you please tell me what the correct mechanism for getting the function to work as expected is?
#include <jni.h>
#include "bbapi.h"
#include "bbunix.h"
#include <stdio.h>
#include "tt.h"
int foo = 5;
int test2(int t) {
return (t + foo);
}
JNIEXPORT jint JNICALL Java_com_bear_calypsox_tk_marketdata_rt_BloombergFeedHandlerImpl_testBloom
(JNIEnv * env, jobject jobj, jint num) {
num = test2(num);
return num;
}
The reason for this simple example is that it describes what will happen when I call a function inside a very large C librbary -- the library utilises lots of global variables and strucutures and therefore will have the same issue surely? Can you please advise how people avoid this when calling into C libraries from Java?
Many thanks for your help.
[1283 byte] By [
cr_javaa] at [2007-10-3 0:56:11]

Hi,
Thanks for your reply. Thant's the point, foo is not modified elsewhere -- what I've shown you is all the code. The value of foo is not 5 -- it's almost as if it's an undefined value i.e. when you access a variable that has been declared but not initialised.
Given that we call directly into these functions i.e. testBloom() and then it calls test2(), when and how would foo ever have been initialised? How would the run-time environment know the value of foo, given it's a global?
The value of num is 65 in the case I am trying. Yes, I am sure of its value. Also, I can further confirm the value of num because when I change foo to a literal value, the value of num returned to the Java side is exactly what I'd expect.Thanks.
What OS and compiler version are you using?
The .init section of the DSO you build contains the initialization code for the C global variables, which is called when the DSO is loaded. Java and the JVM don't get involved. Java's only involvement with the DSO is in its lookup of the entry point for the native method via dlsym() or similar and calling that function through the resulting function pointer.
Have you checked the compilation options on your DSO to make sure everything is correct? You should typically compile with PIC (Position-Independent Code) on UNIX platforms and use the -shared or similar compiler option to generate a shared object. (Presumably you're doing this correctly because otherwise you wouldn't be getting into the native code at all.)
Have you checked the JNI FAQ? http://java.sun.com/products/jdk/faq/jnifaq.html
Have you looked for other JNI examples on the web and tried to deconstruct them to see what is going wrong in your case?