Issues with Java Native Interface

Started by
4 comments, last by Bacon and Eggs 16 years, 9 months ago
I am trying to just get basic things working in JNI... such as in this case being able to retrieve the value of an integer member from a native method of the same class. My java code initializes the integer member jInt to 0 and correctly prints out the results as 0. My native c dll however can access the field, but retrieves the wrong value of 647383456. Here is the output my program spits out... Printing from Java...jInt has value: 0 Printing from c dll..Jint has value: 647383456 If anyone can tell anything I am doing wrong, I would greatly appreciate as this is even more greatly becoming a major source of frustration. I can tell that JNI is finding my integer field correctly because I get a "field could not be found" exception if I use a name other than jInt. The following is source for my simple Java test program

public class Main 
{
    //Members
    public int jInt = 0;
    
    //Methods
    native void CPrint();
    
    void PrintJint()
    {
        System.out.println("Printing from Java...jInt has value: " + jInt + "\n");
    }
   
    public Main() 
    {
        jInt = 0;
        System.loadLibrary( "testnativeclr" );
        jInt = 0;
    }
    
    //Entry Point
    public static void main(String[] args) 
    {
        Main main = new Main();
        main.CPrint();
        main.PrintJint();  
    }   
}

Here is the source for my implementation of the native method CPrint located in the testnativeclr.dll.

#include <iostream>
#include "Main.h"
#include "jni.h"
using namespace std;



JNIEXPORT void JNICALL Java_Main_CPrint(JNIEnv* jEnv, jobject jObj)
{
	jclass Object = jEnv->GetObjectClass( jObj );
	jfieldID IntFieldId = jEnv->GetFieldID( Object, "jInt", "I" );
	jint val = jEnv->GetIntField( Object, IntFieldId );

	cout  << "Printing from c dll..Jint has value: " << val << "\n";
}

Lastly here is Main.h which was generated by the Java binary command line tool javac..

/* DO NOT EDIT THIS FILE - it is machine generated */
#include "jni.h"
/* Header for class Main */

#ifndef _Included_Main
#define _Included_Main
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     Main
 * Method:    CPrint
 * Signature: ()V
 */
JNIEXPORT void JNICALL Java_Main_CPrint
  (JNIEnv *, jobject);

#ifdef __cplusplus
}
#endif
#endif

Advertisement
Are there honestly no Sun engineers in here?

Seriously, for anyone who knows Java Native Interfaces, I would think the problem is rather trivial, but I still have not been able to figure this out... please if anyone knows I really need help on this, either through here or my aim: Ladoga Karelia.
try asking at www.javagaming.org
Did you try checking for exception?

I think it's jEnv->exception() after the jEnv->GetIntField()?
Quote:Original post by Antheus
Did you try checking for exception?

I think it's jEnv->exception() after the jEnv->GetIntField()?


I only get that exception if I put in a field name which doesn't exist.

Are you sure that 647383456 isn't the memory location of which the data is stored and the cout<< operator is printing that off? Somehow I think I'm off base here.

Personally I don't trust anything that's not a string when it comes to java JNI interfaces. That mistrust was embedded ito my psyche a long time ago when I ran into similar issues back when I think I tried this.

This topic is closed to new replies.

Advertisement