Modifications to the typemaps giving users fine control over memory ownership and lifetime of director classes. Patch from Scott Michel.
git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@7070 626c5289-ae23-0410-ae9c-e8d60b6d4f22
This commit is contained in:
parent
827fa350ab
commit
47e471fc7e
3 changed files with 269 additions and 143 deletions
|
|
@ -12,56 +12,125 @@
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|
||||||
|
#if defined(DEBUG_DIRECTOR_OWNED)
|
||||||
|
#include <iostream>
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace Swig {
|
namespace Swig {
|
||||||
|
/* Java object wrapper */
|
||||||
|
class JObjectWrapper {
|
||||||
|
public:
|
||||||
|
JObjectWrapper() : jthis_(NULL), weak_global_(true) {
|
||||||
|
}
|
||||||
|
|
||||||
|
~JObjectWrapper() {
|
||||||
|
jthis_ = NULL;
|
||||||
|
weak_global_ = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool set(JNIEnv *jenv, jobject jobj, bool mem_own, bool weak_global) {
|
||||||
|
if (jthis_ == NULL) {
|
||||||
|
weak_global_ = weak_global;
|
||||||
|
if (jobj)
|
||||||
|
jthis_ = ((weak_global_ || !mem_own) ? jenv->NewWeakGlobalRef(jobj) : jenv->NewGlobalRef(jobj));
|
||||||
|
#if defined(DEBUG_DIRECTOR_OWNED)
|
||||||
|
std::cout << "JObjectWrapper::set(" << jobj << ", " << (weak_global ? "weak_global" : "global_ref") << ") -> " << jthis_ << std::endl;
|
||||||
|
#endif
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
#if defined(DEBUG_DIRECTOR_OWNED)
|
||||||
|
std::cout << "JObjectWrapper::set(" << jobj << ", " << (weak_global ? "weak_global" : "global_ref") << ") -> already set" << std::endl;
|
||||||
|
#endif
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
jobject get(JNIEnv *jenv) const {
|
||||||
|
#if defined(DEBUG_DIRECTOR_OWNED)
|
||||||
|
std::cout << "JObjectWrapper::get(";
|
||||||
|
if (jthis_)
|
||||||
|
std::cout << jthis_;
|
||||||
|
else
|
||||||
|
std::cout << "null";
|
||||||
|
std::cout << ") -> return new local ref" << std::endl;
|
||||||
|
#endif
|
||||||
|
return (jthis_ ? jenv->NewLocalRef(jthis_) : jthis_);
|
||||||
|
}
|
||||||
|
|
||||||
|
void release(JNIEnv *jenv) {
|
||||||
|
#if defined(DEBUG_DIRECTOR_OWNED)
|
||||||
|
std::cout << "JObjectWrapper::release(" << jthis_ << "): " << (weak_global_ ? "local ref" : "global ref") << std::endl;
|
||||||
|
#endif
|
||||||
|
if (weak_global_)
|
||||||
|
jenv->DeleteWeakGlobalRef(jthis_);
|
||||||
|
else
|
||||||
|
jenv->DeleteGlobalRef(jthis_);
|
||||||
|
|
||||||
|
jthis_ = NULL;
|
||||||
|
weak_global_ = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
jobject peek() {
|
||||||
|
return jthis_;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
/* pointer to Java object */
|
||||||
|
jobject jthis_;
|
||||||
|
/* Local or global reference flag */
|
||||||
|
bool weak_global_;
|
||||||
|
};
|
||||||
|
|
||||||
/* director base class */
|
/* director base class */
|
||||||
class Director {
|
class Director {
|
||||||
private:
|
private:
|
||||||
/* pointer to Java virtual machine */
|
/* pointer to Java virtual machine */
|
||||||
JavaVM *swig_jvm;
|
JavaVM *swig_jvm_;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/* pointer to the wrapped Java object */
|
/* Java object wrapper */
|
||||||
jobject swig_self;
|
JObjectWrapper swig_self_;
|
||||||
|
|
||||||
/* Acquire Java VM environment from Java VM */
|
/* Acquire Java VM environment from Java VM */
|
||||||
JNIEnv *swig_acquire_jenv() const {
|
JNIEnv *swig_acquire_jenv() const {
|
||||||
JNIEnv *env = NULL;
|
JNIEnv *env = NULL;
|
||||||
swig_jvm->AttachCurrentThread((void **) &env, NULL);
|
swig_jvm_->AttachCurrentThread((void **) &env, NULL);
|
||||||
return env;
|
return env;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Disconnect director from Java object */
|
/* Disconnect director from Java object */
|
||||||
void swig_disconnect_director_self(const char *disconn_method) {
|
void swig_disconnect_director_self(const char *disconn_method) {
|
||||||
if (swig_self) {
|
|
||||||
JNIEnv *jenv = swig_acquire_jenv();
|
JNIEnv *jenv = swig_acquire_jenv();
|
||||||
jmethodID disconn_meth = jenv->GetMethodID(jenv->GetObjectClass(swig_self), disconn_method, "()V");
|
jobject jobj = swig_self_.get(jenv);
|
||||||
|
#if defined(DEBUG_DIRECTOR_OWNED)
|
||||||
|
std::cout << "Swig::Director::disconnect_director_self(" << jobj << ")" << std::endl;
|
||||||
|
#endif
|
||||||
|
if (jobj) {
|
||||||
|
jmethodID disconn_meth = jenv->GetMethodID(jenv->GetObjectClass(jobj), disconn_method, "()V");
|
||||||
if (disconn_meth) {
|
if (disconn_meth) {
|
||||||
jenv->CallVoidMethod(swig_self, disconn_meth);
|
jenv->CallVoidMethod(jobj, disconn_meth);
|
||||||
} else {
|
} else {
|
||||||
jenv->ExceptionClear();
|
jenv->ExceptionClear();
|
||||||
}
|
}
|
||||||
jenv->DeleteGlobalRef(swig_self);
|
|
||||||
swig_self = (jobject) NULL;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Director(JNIEnv *jenv) : swig_jvm((JavaVM *) NULL), swig_self(NULL) {
|
Director(JNIEnv *jenv) : swig_jvm_((JavaVM *) NULL), swig_self_() {
|
||||||
/* Acquire the Java VM pointer */
|
/* Acquire the Java VM pointer */
|
||||||
jenv->GetJavaVM(&swig_jvm);
|
jenv->GetJavaVM(&swig_jvm_);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual ~Director() {
|
virtual ~Director() {
|
||||||
|
swig_self_.release(swig_acquire_jenv());
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set swig_self and get Java global reference on object */
|
bool swig_set_self(JNIEnv *jenv, jobject jself, bool mem_own, bool weak_global) {
|
||||||
void swig_set_self(JNIEnv *jenv, jobject jself) {
|
return swig_self_.set(jenv, jself, mem_own, weak_global);
|
||||||
swig_self = jenv->NewGlobalRef(jself);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* return a pointer to the wrapped Java object */
|
jobject swig_get_self(JNIEnv *jenv) const {
|
||||||
jobject swig_get_self() const {
|
return swig_self_.get(jenv);
|
||||||
return swig_self;
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -891,34 +891,43 @@
|
||||||
%typemap(javaimports) SWIGTYPE, SWIGTYPE *, SWIGTYPE &, SWIGTYPE [], SWIGTYPE (CLASS::*) ""
|
%typemap(javaimports) SWIGTYPE, SWIGTYPE *, SWIGTYPE &, SWIGTYPE [], SWIGTYPE (CLASS::*) ""
|
||||||
%typemap(javainterfaces) SWIGTYPE, SWIGTYPE *, SWIGTYPE &, SWIGTYPE [], SWIGTYPE (CLASS::*) ""
|
%typemap(javainterfaces) SWIGTYPE, SWIGTYPE *, SWIGTYPE &, SWIGTYPE [], SWIGTYPE (CLASS::*) ""
|
||||||
|
|
||||||
// Proxy classes (base classes, ie, not derived classes)
|
/* javabody typemaps */
|
||||||
%typemap(javabody) SWIGTYPE %{
|
|
||||||
|
%define SWIG_JAVABODY_METHODS(PTRCTOR_VISIBILITY, CPTR_VISIBILITY, TYPENAME...)
|
||||||
|
// Base proxy classes
|
||||||
|
%typemap(javabody) TYPENAME %{
|
||||||
private long swigCPtr;
|
private long swigCPtr;
|
||||||
protected boolean swigCMemOwn;
|
protected boolean swigCMemOwn;
|
||||||
|
|
||||||
protected $javaclassname(long cPtr, boolean cMemoryOwn) {
|
PTRCTOR_VISIBILITY $javaclassname(long cPtr, boolean cMemoryOwn) {
|
||||||
swigCMemOwn = cMemoryOwn;
|
swigCMemOwn = cMemoryOwn;
|
||||||
swigCPtr = cPtr;
|
swigCPtr = cPtr;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static long getCPtr($javaclassname obj) {
|
CPTR_VISIBILITY static long getCPtr($javaclassname obj) {
|
||||||
return (obj == null) ? 0 : obj.swigCPtr;
|
return (obj == null) ? 0 : obj.swigCPtr;
|
||||||
}
|
}
|
||||||
%}
|
%}
|
||||||
|
|
||||||
// Derived proxy classes
|
// Derived proxy classes
|
||||||
%typemap(javabody_derived) SWIGTYPE %{
|
%typemap(javabody_derived) TYPENAME %{
|
||||||
private long swigCPtr;
|
private long swigCPtr;
|
||||||
|
|
||||||
protected $javaclassname(long cPtr, boolean cMemoryOwn) {
|
PTRCTOR_VISIBILITY $javaclassname(long cPtr, boolean cMemoryOwn) {
|
||||||
super($moduleJNI.SWIG$javaclassnameUpcast(cPtr), cMemoryOwn);
|
super($moduleJNI.SWIG$javaclassnameUpcast(cPtr), cMemoryOwn);
|
||||||
swigCPtr = cPtr;
|
swigCPtr = cPtr;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static long getCPtr($javaclassname obj) {
|
CPTR_VISIBILITY static long getCPtr($javaclassname obj) {
|
||||||
return (obj == null) ? 0 : obj.swigCPtr;
|
return (obj == null) ? 0 : obj.swigCPtr;
|
||||||
}
|
}
|
||||||
%}
|
%}
|
||||||
|
%enddef
|
||||||
|
|
||||||
|
/* Set the default for SWIGTYPE: pointer constructor is protected,
|
||||||
|
getCPtr is protected. Season to your own taste! */
|
||||||
|
|
||||||
|
SWIG_JAVABODY_METHODS(protected, protected, SWIGTYPE)
|
||||||
|
|
||||||
// Typewrapper classes
|
// Typewrapper classes
|
||||||
%typemap(javabody) SWIGTYPE *, SWIGTYPE &, SWIGTYPE [], SWIGTYPE (CLASS::*) %{
|
%typemap(javabody) SWIGTYPE *, SWIGTYPE &, SWIGTYPE [], SWIGTYPE (CLASS::*) %{
|
||||||
|
|
@ -943,14 +952,49 @@
|
||||||
}
|
}
|
||||||
%}
|
%}
|
||||||
|
|
||||||
%typemap(javaconstruct) SWIGTYPE {
|
/*
|
||||||
this($imcall, true);
|
* Java constructor typemaps:
|
||||||
}
|
*
|
||||||
|
* The javaconstruct and javaconstruct_director typemaps are inserted when a
|
||||||
|
* proxy class's constructor is generated. These typemaps allow control over what
|
||||||
|
* code is executed in the constructor as well as specifying who owns the
|
||||||
|
* underlying C/C++ object. Normally, Java has ownership and the underlying
|
||||||
|
* C/C++ object is deallocated when the Java object is finalized (swigCMemOwn
|
||||||
|
* is true.) If swigCMemOwn is false, C/C++ is ultimately responsible for
|
||||||
|
* deallocating the underlying object's memory.
|
||||||
|
*
|
||||||
|
* The SWIG_PROXY_CONSTRUCTOR and SWIG_DIRECTOR_CONSTRUCTOR macros define the
|
||||||
|
* javaconstruct and javaconstruct_director typemaps for a proxy class for a
|
||||||
|
* particular TYPENAME. OWNERSHIP is passed as the value of swigCMemOwn to the
|
||||||
|
* pointer constructor method. SWIG_DIRECTOR_CONSTRUCTOR takes an additional
|
||||||
|
* parameter, WEAKREF, that determines which kind of Java object reference
|
||||||
|
* will be used by the C++ director class (WeakGlobalRef vs. GlobalRef.)
|
||||||
|
*
|
||||||
|
* The SWIG_DIRECTOR_OWNED macro sets the ownership of director-based proxy
|
||||||
|
* classes to false, meaning that the underlying C++ object will be
|
||||||
|
* reclaimed by C++.
|
||||||
|
*/
|
||||||
|
|
||||||
%typemap(javaconstruct_director) SWIGTYPE {
|
%define SWIG_PROXY_CONSTRUCTOR(OWNERSHIP, TYPENAME...)
|
||||||
this($imcall, true);
|
%typemap(javaconstruct) TYPENAME {
|
||||||
$moduleJNI.$javaclassname_director_connect(this, swigCPtr);
|
this($imcall, OWNERSHIP);
|
||||||
}
|
}
|
||||||
|
%enddef
|
||||||
|
|
||||||
|
%define SWIG_DIRECTOR_CONSTRUCTOR(OWNERSHIP, WEAKREF, TYPENAME...)
|
||||||
|
%typemap(javaconstruct_director) TYPENAME {
|
||||||
|
this($imcall, OWNERSHIP);
|
||||||
|
$moduleJNI.$javaclassname_director_connect(this, swigCPtr, OWNERSHIP, WEAKREF);
|
||||||
|
}
|
||||||
|
%enddef
|
||||||
|
|
||||||
|
%define SWIG_DIRECTOR_OWNED(TYPENAME...)
|
||||||
|
SWIG_DIRECTOR_CONSTRUCTOR(true, false, TYPENAME)
|
||||||
|
%enddef
|
||||||
|
|
||||||
|
// Set the default for SWIGTYPE: Java owns the C/C++ object.
|
||||||
|
SWIG_PROXY_CONSTRUCTOR(true, SWIGTYPE)
|
||||||
|
SWIG_DIRECTOR_CONSTRUCTOR(true, true, SWIGTYPE)
|
||||||
|
|
||||||
%typemap(javadestruct, methodname="delete") SWIGTYPE {
|
%typemap(javadestruct, methodname="delete") SWIGTYPE {
|
||||||
if(swigCPtr != 0 && swigCMemOwn) {
|
if(swigCPtr != 0 && swigCMemOwn) {
|
||||||
|
|
|
||||||
|
|
@ -75,7 +75,6 @@ class JAVA : public Language {
|
||||||
Hash *dmethods_table;
|
Hash *dmethods_table;
|
||||||
int n_dmethods;
|
int n_dmethods;
|
||||||
int n_directors;
|
int n_directors;
|
||||||
bool emitted_connect;
|
|
||||||
int first_class_dmethod;
|
int first_class_dmethod;
|
||||||
int curr_class_dmethod;
|
int curr_class_dmethod;
|
||||||
|
|
||||||
|
|
@ -139,8 +138,7 @@ class JAVA : public Language {
|
||||||
dmethods_seq(NULL),
|
dmethods_seq(NULL),
|
||||||
dmethods_table(NULL),
|
dmethods_table(NULL),
|
||||||
n_dmethods(0),
|
n_dmethods(0),
|
||||||
n_directors(0),
|
n_directors(0)
|
||||||
emitted_connect(false)
|
|
||||||
{
|
{
|
||||||
/* for now, multiple inheritance in directors is disabled, this
|
/* for now, multiple inheritance in directors is disabled, this
|
||||||
should be easy to implement though */
|
should be easy to implement though */
|
||||||
|
|
@ -340,7 +338,6 @@ class JAVA : public Language {
|
||||||
dmethods_table = NewHash();
|
dmethods_table = NewHash();
|
||||||
n_dmethods = 0;
|
n_dmethods = 0;
|
||||||
n_directors = 0;
|
n_directors = 0;
|
||||||
emitted_connect = false;
|
|
||||||
if (!package) package = NewString("");
|
if (!package) package = NewString("");
|
||||||
jnipackage = NewString("");
|
jnipackage = NewString("");
|
||||||
package_path = NewString("");
|
package_path = NewString("");
|
||||||
|
|
@ -562,7 +559,6 @@ class JAVA : public Language {
|
||||||
Delete(dmethods_seq); dmethods_seq = NULL;
|
Delete(dmethods_seq); dmethods_seq = NULL;
|
||||||
Delete(dmethods_table); dmethods_table = NULL;
|
Delete(dmethods_table); dmethods_table = NULL;
|
||||||
n_dmethods = 0;
|
n_dmethods = 0;
|
||||||
emitted_connect = false;
|
|
||||||
|
|
||||||
/* Close all of the files */
|
/* Close all of the files */
|
||||||
Dump(f_header,f_runtime);
|
Dump(f_header,f_runtime);
|
||||||
|
|
@ -1490,6 +1486,7 @@ class JAVA : public Language {
|
||||||
String *baseclass = NULL;
|
String *baseclass = NULL;
|
||||||
String *c_baseclassname = NULL;
|
String *c_baseclassname = NULL;
|
||||||
String *typemap_lookup_type = Getattr(n,"classtypeobj");
|
String *typemap_lookup_type = Getattr(n,"classtypeobj");
|
||||||
|
bool feature_director = Swig_directorclass(n);
|
||||||
|
|
||||||
/* Deal with inheritance */
|
/* Deal with inheritance */
|
||||||
List *baselist = Getattr(n,"bases");
|
List *baselist = Getattr(n,"bases");
|
||||||
|
|
@ -1580,7 +1577,7 @@ class JAVA : public Language {
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Insert declaration for directordisconnect/directordisconnect_derived typemap, if this class has directors enabled */
|
/* Insert declaration for directordisconnect/directordisconnect_derived typemap, if this class has directors enabled */
|
||||||
if (Swig_directorclass(n)) {
|
if (feature_director) {
|
||||||
const String *disconn_tm = NULL;
|
const String *disconn_tm = NULL;
|
||||||
Node *disconn_attr = NewHash();
|
Node *disconn_attr = NewHash();
|
||||||
String *disconn_methodname = NULL;
|
String *disconn_methodname = NULL;
|
||||||
|
|
@ -1749,7 +1746,7 @@ class JAVA : public Language {
|
||||||
Printf(dcast_wrap->code, " jobject jresult = (jobject) 0;\n");
|
Printf(dcast_wrap->code, " jobject jresult = (jobject) 0;\n");
|
||||||
Printf(dcast_wrap->code, " %s *obj = *((%s **) &jCPtrBase);\n", norm_name, norm_name);
|
Printf(dcast_wrap->code, " %s *obj = *((%s **) &jCPtrBase);\n", norm_name, norm_name);
|
||||||
Printf(dcast_wrap->code, " if (obj) director = dynamic_cast<Swig::Director *>(obj);\n");
|
Printf(dcast_wrap->code, " if (obj) director = dynamic_cast<Swig::Director *>(obj);\n");
|
||||||
Printf(dcast_wrap->code, " if (director) jresult = director->swig_get_self();\n");
|
Printf(dcast_wrap->code, " if (director) jresult = director->swig_get_self(jenv);\n");
|
||||||
Printf(dcast_wrap->code, " return jresult;\n");
|
Printf(dcast_wrap->code, " return jresult;\n");
|
||||||
Printf(dcast_wrap->code, "}\n");
|
Printf(dcast_wrap->code, "}\n");
|
||||||
|
|
||||||
|
|
@ -1757,14 +1754,13 @@ class JAVA : public Language {
|
||||||
DelWrapper(dcast_wrap);
|
DelWrapper(dcast_wrap);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
emitDirectorExtraMethods(n);
|
||||||
|
|
||||||
Delete(proxy_class_name); proxy_class_name = NULL;
|
Delete(proxy_class_name); proxy_class_name = NULL;
|
||||||
Delete(destructor_call); destructor_call = NULL;
|
Delete(destructor_call); destructor_call = NULL;
|
||||||
Delete(proxy_class_constants_code); proxy_class_constants_code = NULL;
|
Delete(proxy_class_constants_code); proxy_class_constants_code = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Reinitialize per-class director vars */
|
|
||||||
emitted_connect = false;
|
|
||||||
|
|
||||||
return SWIG_OK;
|
return SWIG_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2075,45 +2071,6 @@ class JAVA : public Language {
|
||||||
Printf(function_code, "\n");
|
Printf(function_code, "\n");
|
||||||
Replaceall(function_code, "$imcall", imcall);
|
Replaceall(function_code, "$imcall", imcall);
|
||||||
|
|
||||||
/* Add director connection call if this class has directors. */
|
|
||||||
|
|
||||||
if (feature_director) {
|
|
||||||
String *jni_imclass_name = makeValidJniName(imclass_name);
|
|
||||||
String *norm_name = SwigType_namestr(Getattr(n, "name"));
|
|
||||||
|
|
||||||
String *swig_director_connect = NewStringf("%s_director_connect", proxy_class_name);
|
|
||||||
// Printv(function_code, " ", imclass_name, ".", swig_director_connect, "(this, swigCPtr);\n", NIL);
|
|
||||||
|
|
||||||
if (!emitted_connect) {
|
|
||||||
String *swig_director_connect_jni = makeValidJniName(swig_director_connect);
|
|
||||||
Wrapper *conn_wrap;
|
|
||||||
|
|
||||||
Printf(imclass_class_code, " public final static native void %s(%s obj, long cptr);\n", swig_director_connect,
|
|
||||||
proxy_class_name);
|
|
||||||
|
|
||||||
conn_wrap = NewWrapper();
|
|
||||||
Printf(conn_wrap->def, "JNIEXPORT void JNICALL Java_%s%s_%s(JNIEnv *jenv, jclass jcls, jobject jself, jlong objarg) {",
|
|
||||||
jnipackage, jni_imclass_name, swig_director_connect_jni);
|
|
||||||
Printf(conn_wrap->code, " %s *obj = *((%s **) &objarg);\n", norm_name, norm_name);
|
|
||||||
Printf(conn_wrap->code, " (void)jcls;\n");
|
|
||||||
Printf(conn_wrap->code, " SwigDirector_%s *director = dynamic_cast<SwigDirector_%s *>(obj);\n",
|
|
||||||
Getattr(n, "sym:name"), Getattr(n, "sym:name"));
|
|
||||||
Printf(conn_wrap->code, " if (director) {\n");
|
|
||||||
Printf(conn_wrap->code, " director->swig_connect_director(jenv, jself, jenv->GetObjectClass(jself));\n");
|
|
||||||
Printf(conn_wrap->code, " }\n");
|
|
||||||
Printf(conn_wrap->code, "}\n");
|
|
||||||
|
|
||||||
Wrapper_print(conn_wrap, f_wrappers);
|
|
||||||
DelWrapper(conn_wrap);
|
|
||||||
|
|
||||||
Delete(swig_director_connect_jni);
|
|
||||||
emitted_connect = true;
|
|
||||||
}
|
|
||||||
Delete(norm_name);
|
|
||||||
Delete(jni_imclass_name);
|
|
||||||
Delete(swig_director_connect);
|
|
||||||
}
|
|
||||||
|
|
||||||
Printv(proxy_class_code, function_code, "\n", NIL);
|
Printv(proxy_class_code, function_code, "\n", NIL);
|
||||||
|
|
||||||
Delete(overloaded_name);
|
Delete(overloaded_name);
|
||||||
|
|
@ -2777,6 +2734,49 @@ class JAVA : public Language {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*----------------------------------------------------------------------
|
||||||
|
* emitDirectorExtraMethods()
|
||||||
|
*
|
||||||
|
* This is where the $javaclassname_director_connect is
|
||||||
|
* generated.
|
||||||
|
*--------------------------------------------------------------------*/
|
||||||
|
void emitDirectorExtraMethods(Node *n)
|
||||||
|
{
|
||||||
|
if (Swig_directorclass(n)) {
|
||||||
|
String *jni_imclass_name = makeValidJniName(imclass_name);
|
||||||
|
String *norm_name = SwigType_namestr(Getattr(n, "name"));
|
||||||
|
String *swig_director_connect = NewStringf("%s_director_connect", proxy_class_name);
|
||||||
|
String *swig_director_connect_jni = makeValidJniName(swig_director_connect);
|
||||||
|
Wrapper *code_wrap;
|
||||||
|
|
||||||
|
Printf(imclass_class_code, " public final static native void %s(%s obj, long cptr, boolean mem_own, boolean weak_global);\n",
|
||||||
|
swig_director_connect, proxy_class_name);
|
||||||
|
|
||||||
|
code_wrap = NewWrapper();
|
||||||
|
Printf(code_wrap->def,
|
||||||
|
"JNIEXPORT void JNICALL Java_%s%s_%s(JNIEnv *jenv, jclass jcls, jobject jself, jlong objarg, jboolean jswig_mem_own, "
|
||||||
|
"jboolean jweak_global) {\n",
|
||||||
|
jnipackage, jni_imclass_name, swig_director_connect_jni);
|
||||||
|
Printf(code_wrap->code, " %s *obj = *((%s **) &objarg);\n", norm_name, norm_name);
|
||||||
|
Printf(code_wrap->code, " (void)jcls;\n");
|
||||||
|
Printf(code_wrap->code, " SwigDirector_%s *director = dynamic_cast<SwigDirector_%s *>(obj);\n",
|
||||||
|
Getattr(n, "sym:name"), Getattr(n, "sym:name"));
|
||||||
|
Printf(code_wrap->code, " if (director) {\n");
|
||||||
|
Printf(code_wrap->code, " director->swig_connect_director(jenv, jself, jenv->GetObjectClass(jself), "
|
||||||
|
"(jswig_mem_own == JNI_TRUE), (jweak_global == JNI_TRUE));\n");
|
||||||
|
Printf(code_wrap->code, " }\n");
|
||||||
|
Printf(code_wrap->code, "}\n");
|
||||||
|
|
||||||
|
Wrapper_print(code_wrap, f_wrappers);
|
||||||
|
DelWrapper(code_wrap);
|
||||||
|
|
||||||
|
Delete(swig_director_connect_jni);
|
||||||
|
Delete(norm_name);
|
||||||
|
Delete(jni_imclass_name);
|
||||||
|
Delete(swig_director_connect);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* ---------------------------------------------------------------
|
/* ---------------------------------------------------------------
|
||||||
* Canonicalize the JNI field descriptor
|
* Canonicalize the JNI field descriptor
|
||||||
*
|
*
|
||||||
|
|
@ -2859,7 +2859,7 @@ class JAVA : public Language {
|
||||||
String *jniret_desc = NewString("");
|
String *jniret_desc = NewString("");
|
||||||
String *classret_desc = NewString("");
|
String *classret_desc = NewString("");
|
||||||
SwigType *jniret_type = NULL;
|
SwigType *jniret_type = NULL;
|
||||||
String *jupcall_args = NewString("swig_get_self()");
|
String *jupcall_args = NewString("swig_get_self(jenv)");
|
||||||
String *imclass_dmethod;
|
String *imclass_dmethod;
|
||||||
Wrapper *imw = NewWrapper();
|
Wrapper *imw = NewWrapper();
|
||||||
String *imcall_args = NewString("");
|
String *imcall_args = NewString("");
|
||||||
|
|
@ -2888,8 +2888,28 @@ class JAVA : public Language {
|
||||||
if (!(SwigType_ispointer(returntype) || SwigType_isreference(returntype))) {
|
if (!(SwigType_ispointer(returntype) || SwigType_isreference(returntype))) {
|
||||||
Wrapper_add_localv(w, "result", SwigType_lstr(returntype, "result"), NIL);
|
Wrapper_add_localv(w, "result", SwigType_lstr(returntype, "result"), NIL);
|
||||||
} else {
|
} else {
|
||||||
/* initialize pointers to something sane. */
|
String *base_typename = SwigType_base(returntype);
|
||||||
|
Symtab *symtab = Getattr(n, "sym:symtab");
|
||||||
|
Node *typenode = Swig_symbol_clookup(base_typename, symtab);
|
||||||
|
|
||||||
|
if (SwigType_ispointer(returntype) || (typenode != NULL && Getattr(typenode, "abstract"))) {
|
||||||
|
/* initialize pointers to something sane. Same for abstract
|
||||||
|
classes when a reference is returned. */
|
||||||
Wrapper_add_localv(w, "result", SwigType_lstr(returntype, "result"), "= 0", NIL);
|
Wrapper_add_localv(w, "result", SwigType_lstr(returntype, "result"), "= 0", NIL);
|
||||||
|
} else {
|
||||||
|
/* If returning a reference, initialize the pointer to a sane
|
||||||
|
default */
|
||||||
|
String *non_ref_type = Copy(returntype);
|
||||||
|
|
||||||
|
/* Remove reference and const qualifiers */
|
||||||
|
Replaceall(non_ref_type, "r.", "");
|
||||||
|
Replaceall(non_ref_type, "q(const).", "");
|
||||||
|
Wrapper_add_localv(w, "result_default", "static", SwigType_str(non_ref_type, "result_default"),
|
||||||
|
"=", SwigType_str(non_ref_type, "()"), NIL);
|
||||||
|
Wrapper_add_localv(w, "result", SwigType_lstr(returntype, "result"), "= &result_default", NIL);
|
||||||
|
|
||||||
|
Delete(non_ref_type);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
SwigType *vt;
|
SwigType *vt;
|
||||||
|
|
@ -3455,7 +3475,7 @@ class JAVA : public Language {
|
||||||
|
|
||||||
Printf(f_directors_h, "%s {\n", Getattr(n, "director:decl"));
|
Printf(f_directors_h, "%s {\n", Getattr(n, "director:decl"));
|
||||||
Printf(f_directors_h, "\npublic:\n");
|
Printf(f_directors_h, "\npublic:\n");
|
||||||
Printf(f_directors_h, " void swig_connect_director(JNIEnv *jenv, jobject jself, jclass jcls);\n");
|
Printf(f_directors_h, " void swig_connect_director(JNIEnv *jenv, jobject jself, jclass jcls, bool swig_mem_own, bool weak_global);\n");
|
||||||
|
|
||||||
/* Keep track of the director methods for this class */
|
/* Keep track of the director methods for this class */
|
||||||
first_class_dmethod = curr_class_dmethod = n_dmethods;
|
first_class_dmethod = curr_class_dmethod = n_dmethods;
|
||||||
|
|
@ -3526,7 +3546,7 @@ class JAVA : public Language {
|
||||||
internal_classname = NewStringf("%s", classname);
|
internal_classname = NewStringf("%s", classname);
|
||||||
|
|
||||||
Wrapper_add_localv(w, "baseclass", "static jclass baseclass", " = 0", NIL);
|
Wrapper_add_localv(w, "baseclass", "static jclass baseclass", " = 0", NIL);
|
||||||
Printf(w->def, "void %s::swig_connect_director(JNIEnv *jenv, jobject jself, jclass jcls) {", director_classname);
|
Printf(w->def, "void %s::swig_connect_director(JNIEnv *jenv, jobject jself, jclass jcls, bool swig_mem_own, bool weak_global) {", director_classname);
|
||||||
|
|
||||||
if (first_class_dmethod != curr_class_dmethod) {
|
if (first_class_dmethod != curr_class_dmethod) {
|
||||||
Printf(w->def, "static struct {\n");
|
Printf(w->def, "static struct {\n");
|
||||||
|
|
@ -3547,7 +3567,7 @@ class JAVA : public Language {
|
||||||
Printf(w->def, "};\n");
|
Printf(w->def, "};\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
Printf(w->code, "swig_set_self(jenv, jself);\n");
|
Printf(w->code, "if (swig_set_self(jenv, jself, swig_mem_own, weak_global)) {\n");
|
||||||
Printf(w->code, "if (baseclass == NULL) {\n");
|
Printf(w->code, "if (baseclass == NULL) {\n");
|
||||||
Printf(w->code, "baseclass = jenv->FindClass(\"%s\");\n", internal_classname);
|
Printf(w->code, "baseclass = jenv->FindClass(\"%s\");\n", internal_classname);
|
||||||
Printf(w->code, "if (baseclass == NULL) return;\n");
|
Printf(w->code, "if (baseclass == NULL) return;\n");
|
||||||
|
|
@ -3589,6 +3609,7 @@ class JAVA : public Language {
|
||||||
|
|
||||||
Printf(f_directors_h, "};\n\n");
|
Printf(f_directors_h, "};\n\n");
|
||||||
Printf(w->code, "}\n");
|
Printf(w->code, "}\n");
|
||||||
|
Printf(w->code, "}\n");
|
||||||
|
|
||||||
Wrapper_print(w, f_directors);
|
Wrapper_print(w, f_directors);
|
||||||
|
|
||||||
|
|
@ -3637,14 +3658,6 @@ class JAVA : public Language {
|
||||||
* ----------------------------------------------------------------------------- */
|
* ----------------------------------------------------------------------------- */
|
||||||
|
|
||||||
virtual int abstractClassTest(Node *n) {
|
virtual int abstractClassTest(Node *n) {
|
||||||
/*
|
|
||||||
This is not needed anymore, since Language::abstractClassTest
|
|
||||||
implements now a test considering the director case, which can
|
|
||||||
be abstract.
|
|
||||||
|
|
||||||
if (!Cmp(Getattr(n, "feature:director"), "1"))
|
|
||||||
return 0;
|
|
||||||
*/
|
|
||||||
return Language::abstractClassTest(n);
|
return Language::abstractClassTest(n);
|
||||||
}
|
}
|
||||||
}; /* class JAVA */
|
}; /* class JAVA */
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue