mirror of https://github.com/swig/swig
Fix Java swigReleaseOwnership() and swigTakeOwnership() regression
Fixes segfault when using non-director classes. Restores a dynamic_cast which was previously removed. The dynamic_cast is not needed for the swig_connect_director call ... we'll have to find another solution for #449 for Java. Closes #1184
This commit is contained in:
parent
3ce3ce0683
commit
b4f4ce4fd5
|
@ -7,6 +7,10 @@ the issue number to the end of the URL: https://github.com/swig/swig/issues/
|
|||
Version 4.0.0 (in progress)
|
||||
===========================
|
||||
|
||||
2018-03-09: fultonwi
|
||||
[Java] #1184 Fix swigReleaseOwnership() and swigTakeOwnership() regression
|
||||
for non-director classes. Restores a dynamic_cast which was previously removed.
|
||||
|
||||
2018-03-07: llongi
|
||||
Github PR #1166 - Fix preprocessor handling of macros with commas
|
||||
in a // comment.
|
||||
|
|
|
@ -194,6 +194,7 @@ CPP_TEST_CASES += \
|
|||
director_nspace_director_name_collision \
|
||||
director_overload \
|
||||
director_overload2 \
|
||||
director_ownership \
|
||||
director_pass_by_value \
|
||||
director_primitives \
|
||||
director_property \
|
||||
|
|
|
@ -0,0 +1,72 @@
|
|||
%module(directors="1") director_ownership
|
||||
|
||||
// Github issue #1184
|
||||
|
||||
%include "std_string.i"
|
||||
|
||||
%feature("director") example::ContentBase;
|
||||
%feature("director") example::ContentDerived;
|
||||
|
||||
%newobject example::make_content;
|
||||
|
||||
%inline %{
|
||||
#include <string>
|
||||
|
||||
namespace example
|
||||
{
|
||||
|
||||
class ContentBase
|
||||
{
|
||||
public:
|
||||
ContentBase() {}
|
||||
virtual ~ContentBase() {}
|
||||
virtual std::string get_name() const = 0;
|
||||
};
|
||||
|
||||
|
||||
class ContentDerived: public ContentBase
|
||||
{
|
||||
public:
|
||||
ContentDerived():ContentBase() { m_name = "ContentDerived"; }
|
||||
virtual ~ContentDerived() {}
|
||||
virtual std::string get_name() const override { return m_name; }
|
||||
|
||||
private:
|
||||
std::string m_name;
|
||||
};
|
||||
|
||||
|
||||
class Container
|
||||
{
|
||||
public:
|
||||
Container() { m_content = 0; }
|
||||
~Container()
|
||||
{
|
||||
clear_content();
|
||||
}
|
||||
// the container takes the ownership of the content
|
||||
void set_content(ContentBase* content)
|
||||
{
|
||||
clear_content();
|
||||
m_content = content;
|
||||
}
|
||||
ContentBase* get_content() { return m_content; }
|
||||
|
||||
private:
|
||||
void clear_content()
|
||||
{
|
||||
if(m_content)
|
||||
{
|
||||
delete m_content;
|
||||
m_content = 0;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
ContentBase* m_content;
|
||||
};
|
||||
|
||||
static ContentBase* make_content() { return new ContentDerived(); }
|
||||
|
||||
} // namespace example
|
||||
%}
|
|
@ -0,0 +1,42 @@
|
|||
import director_ownership.*;
|
||||
|
||||
public class director_ownership_runme {
|
||||
|
||||
static {
|
||||
try {
|
||||
System.loadLibrary("director_ownership");
|
||||
} catch (UnsatisfiedLinkError e) {
|
||||
System.err.println("Native code library failed to load. See the chapter on Dynamic Linking Problems in the SWIG Java documentation for help.\n" + e);
|
||||
System.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
public static void set_content_and_release(Container container, ContentBase content) {
|
||||
content.swigReleaseOwnership();
|
||||
container.set_content(content);
|
||||
}
|
||||
|
||||
public static void main(String argv[]) {
|
||||
|
||||
Container container = new Container();
|
||||
|
||||
// make a content in java (cMemoryOwn true)
|
||||
ContentBase content_java = new ContentDerived();
|
||||
|
||||
// make a content in c++ (cMemoryOwn true)
|
||||
ContentBase content_cpp = director_ownership.make_content();
|
||||
|
||||
set_content_and_release(container, content_java);
|
||||
if (!container.get_content().get_name().equals("ContentDerived"))
|
||||
throw new RuntimeException("did not get ContentDerived");
|
||||
|
||||
// when swigReleaseOwnership() is called on content_cpp, swig tries a static_cast to director and calls the method
|
||||
// director->swig_java_change_ownership. The content created in c++ native library is not a director, therefore a
|
||||
// segfault may occur.
|
||||
// With a check done using dynamic_cast this issue could be avoided.
|
||||
set_content_and_release(container, content_cpp);
|
||||
if (!container.get_content().get_name().equals("ContentDerived"))
|
||||
throw new RuntimeException("did not get ContentDerived");
|
||||
}
|
||||
}
|
||||
|
|
@ -3763,15 +3763,16 @@ public:
|
|||
Printf(code_wrap->code, " %s *obj = *((%s **)&objarg);\n", smartptr, smartptr);
|
||||
Printf(code_wrap->code, " // Keep a local instance of the smart pointer around while we are using the raw pointer\n");
|
||||
Printf(code_wrap->code, " // Avoids using smart pointer specific API.\n");
|
||||
Printf(code_wrap->code, " %s *director = static_cast<%s *>(obj->operator->());\n", dirClassName, dirClassName);
|
||||
}
|
||||
else {
|
||||
Printf(code_wrap->code, " %s *director = dynamic_cast<%s *>(obj->operator->());\n", dirClassName, dirClassName);
|
||||
} else {
|
||||
Printf(code_wrap->code, " %s *obj = *((%s **)&objarg);\n", norm_name, norm_name);
|
||||
Printf(code_wrap->code, " %s *director = static_cast<%s *>(obj);\n", dirClassName, dirClassName);
|
||||
Printf(code_wrap->code, " %s *director = dynamic_cast<%s *>(obj);\n", dirClassName, dirClassName);
|
||||
}
|
||||
|
||||
Printf(code_wrap->code, " (void)jcls;\n");
|
||||
Printf(code_wrap->code, " director->swig_java_change_ownership(jenv, jself, jtake_or_release ? true : false);\n");
|
||||
Printf(code_wrap->code, " if (director) {\n");
|
||||
Printf(code_wrap->code, " director->swig_java_change_ownership(jenv, jself, jtake_or_release ? true : false);\n");
|
||||
Printf(code_wrap->code, " }\n");
|
||||
Printf(code_wrap->code, "}\n");
|
||||
|
||||
Wrapper_print(code_wrap, f_wrappers);
|
||||
|
|
Loading…
Reference in New Issue