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

Glenn Chambers gchamber@bright.net
Tue Dec 25 02:56:00 GMT 2007


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.


More information about the Java mailing list

AltStyle によって変換されたページ (->オリジナル) /