• Post Reply Bookmark Topic Watch Topic
  • New Topic

weird JNI problem  RSS feed

 
John P. Hughes
Greenhorn
Posts: 9
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I'm writing a Java class called BigZ that taps into the GNU Multiple-Precision Arithmetic Library's integer code. The code below prints 42.

BigZ z1 = new BigZ(42);
System.out.println(z1);

But the code below prints 12!

BigZ z1 = new BigZ(42),
z2 = new BigZ(12);
System.out.println(z1);

I've gotten some strange results from JNI code before, but I've never seen anything so odd as this. Does anyone know why z1 and z2 are sharing an instance field?
 
Scott Johnson
Ranch Hand
Posts: 518
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Did you define one of the fields in BigZ to be static?

Post your code so we can see what's happening.
 
John P. Hughes
Greenhorn
Posts: 9
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Here's the first bit of BigZ.

abstract class Ptr {}

public final class BigZ extends Number implements Comparable
{
private Ptr val;

public BigZ(long z)
{
init(z);
}

public static native init();
public native init(long z);

static
{
System.loadLibrary("bigz");
init();
}
}

And here is some of BigZ.c.

static jfieldID val;

JNIEXPORT void JNICALL Java_bignum_BigZ_init__(JNIEnv* env, jclass cls)
{
val = (*env)->GetFieldID(env, cls, "val", "Lbignum/Ptr;");
}

JNIEXPORT void JNICALL Java_bignum_BigZ_init__J(JNIEnv* env, jobject o, jlong z)
{
mpz_ptr thisPtr;

mpz_init(thisPtr);
(*env)->SetObjectField(env, o, val, (jobject)thisPtr);
mpz_set_si(thisPtr, (long)z);
}
 
Peter Chase
Ranch Hand
Posts: 1970
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I have to admit that I cannot see what is wrong here. If someone solves it, I shall be interested to get the answer.

Part of the difficulty is that the code seems to be written to be as confusing as possible. Two methods, both called "init", with different functions, and one static, one not. Likewise, a Java and a C field, both called "var", again with completely different functions. And a variable called "thisPtr" that isn't the "this" pointer. What's all that about, eh?
 
Ernest Friedman-Hill
author and iconoclast
Sheriff
Posts: 24215
37
Chrome Eclipse IDE Mac OS X
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
There's a bunch of things you're not showing us, and some things you aren't that wouldn't compile (one of the init methods in Java has no return type.)

Anyway, here's what I think. I don't know anything about this math library you're using, but I bet you're using it wrong. "thisPtr" is an automatic variable, meaning that the storage it uses (on the stack) is reused after the function exits. I bet that when you call this method multiple times, you're overwriting that same stack storage area, and that's why all the BigZ objects seem to share the same storage (because they do.)
 
John P. Hughes
Greenhorn
Posts: 9
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
The naming makes sense to me. In any case, the choice of identifiers has nothing to do with the problem.
 
John P. Hughes
Greenhorn
Posts: 9
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Mr. Friedman-Hill was right; I was misusing the GMP library. I haven't written C for a while, and so I had forgotten about C's memory management.

I changed BigZ's field type to int and rewrote the C so that it now explicitly allocates memory for the GMP integers. The new code is working.

I originally made BigZ's field of dummy type Ptr so that my code would work on 64-bit machines as well as 32-bit ones. I still can't get my code to work with the field of type Ptr, but at least now I have a grip on the GMP end of things.

Thanks for the help! :-)
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!