This is the mail archive of the java@gcc.gnu.org mailing list for the Java project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Will cni be the sane native interface to c++ in openjdk U gcj?


On Mon, 2007-12-24 at 13:51 -0800, ter wrote:
> Hi,
> 
> This is a development question from a user's point of view. Not a
> compiler writer myself. I am using swig (a great program) right now to
> write a java binding for an existing c++ library.  c++ is flattened to c
> on the native side, and then rebuilt back into objects on the java side.
> I understand cni is a much better approach. The binding from cni into
> full c++ would be much less complex, especially if the c++ code has good
> separation between interface and implementation.

It's been a few years since I last played seriously in this area, but at
that point, there were enough impedance mis-matches between C++ objects
and Java objects that C-style glue layers turned out to be necessary.

In particular, code that threw or caught C++ exceptions couldn't also
throw and catch Java exceptions.  This may have changed in recent
versions; I'll let the developers clarify that point.

Given a C++ library like this (excuse any C++ syntax errors, I'm out
of practice, and I don't have time to compile my examples):

[C++ file myLibrary.h ]
class myLibrary {
	class operationFailed { };

	public myLibrary(int options);
	public ~myLibrary();

	public void majorOperation(int scale) throws operationFailed;
	public int minorOperation(int flavor) throws operationFailed;
}

You would need an adapter class something like this (you'll need
to use java types instead of C++ native types in a lot of places
here; again, I'm pseudo-coding, not publishing tested code):

[Java file myLibraryGlue.java ]
public class myLibraryGlue {
	class operationFailedGlue : Exception { }

	public myLibraryGlue() native;
	public void majorOperation(int scale) native;
	public int minorOperation(int flavor) native;

	// I've forgotten what the correct type is here.
	// Check the CNI documentation.
	private RawPtr ownedLibraryObject;

	// Omitting details of the finalizer that calls the 
	// owned object's destructor
}

[C++ file glue.h ]

class myLibrary;

// This should really be in a class, or namespace.
struct intResult {
	int result;
	void *exception;
};

void *majorOperationGlue(myLibrary *m, int scale);
intResult minorOperationGlue(myLibrary *m, int flavor);

[C++ nativeMethods.cpp]

#include <cni.h>
#include "myLibraryGlue.h"	// From GCJH
#include "glue.h"

// Do NOT include "myLibrary.h" in this file.

void myLibraryGlue::myLibraryGlue()
{
	ownedLibraryObject = (RawPtr) new myLibrary();
}

void myLibraryGlue::majorOperation(int scale)
{
	myLibrary *m = (myLibrary *) ownedLibraryObject;
	void *exception = majorOperationGlue(m, scale);
	if (exception != null) {
		// The below should extract the exception
		// details, and add them to the Java exception
		throw new operationFailed();
	}
}

int myLibraryGlue::minorOperation(myLibrary *m, int scale)
{
	myLibrary *m = (myLibrary *) ownedLibraryObject;
	intResult x = minorOperationGlue(m, scale);
	if (x.exception != null) {
		// The below should extract the exception
		// details, and add them to the Java exception
		throw new operationFailed();
	}

	return x.result;
}

[C++ File NativeGlue.cpp ]

// Do *NOT* include GCJ.H or any Java headers in this file.

#include "glue.h"
#include "myLibrary.h"

void *majorOperationGlue(myLibrary self, int scale)
{
	try {
		self.majorOperation(scale);
	}
	catch (operationFailed *f) {
		return (void *) f;
	}
	return null;
}

void *minorOperationGlue(myLibrary self, int flavor)
{
	intResult r;

	r.result = 0;
	r.exception = (void *) 0;
	try {
		r.result = self.minorOperation(flavor);
	}
	catch (operationFailed *f) {
		r.exception = (void *) f;
	}

	return r;
}

'nativeMethods.cpp' is compiled in 'Java' context, with the
Java exception handling personality.

'nativeGlue.cpp' is compiled in 'C++' context, with the native
C++ exception handling personality.

If your C++ library does not use exceptions, then the glue
layer is not required.



Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]