From 25eaee49f3cb4348e71b66144e9ba541c0632fa5 Mon Sep 17 00:00:00 2001 From: "Brant K. Kyser" Date: Mon, 15 Apr 2013 13:38:40 -0500 Subject: [PATCH] Add check for smart pointer type in generated code for director connection. This fixes a crash in the generated code caused by the dynamic_cast returning 0 because the specified types are incorrect for smart pointer types. Add runtime test to the C# test suite's director smartptr test that demonstrates crash in generated code when directors are used with smart pointer types. Closes #34 --- .../csharp/director_smartptr_runme.cs | 41 +++++++++++++++++++ Source/Modules/csharp.cxx | 14 ++++++- 2 files changed, 53 insertions(+), 2 deletions(-) create mode 100644 Examples/test-suite/csharp/director_smartptr_runme.cs diff --git a/Examples/test-suite/csharp/director_smartptr_runme.cs b/Examples/test-suite/csharp/director_smartptr_runme.cs new file mode 100644 index 000000000..ad33c4d34 --- /dev/null +++ b/Examples/test-suite/csharp/director_smartptr_runme.cs @@ -0,0 +1,41 @@ +using director_smartptrNamespace; + +public class runme +{ + + private class director_smartptr_MyBarFoo : Foo + { + public override string ping() + { + return "director_smartptr_MyBarFoo.ping();"; + } + + public override string pong() + { + return "director_smartptr_MyBarFoo.pong();" + ping(); + } + + public override string fooBar(FooBar fooBar) + { + return fooBar.FooBarDo(); + } + + public override Foo makeFoo() + { + return new Foo(); + } + + public override FooBar makeFooBar() + { + return new FooBar(); + } + } + + static void Main() + { + director_smartptr_MyBarFoo myBarFoo = + new director_smartptr_MyBarFoo(); + + myBarFoo.ping(); + } +} diff --git a/Source/Modules/csharp.cxx b/Source/Modules/csharp.cxx index 4ef62d2cc..2050f36db 100644 --- a/Source/Modules/csharp.cxx +++ b/Source/Modules/csharp.cxx @@ -3382,6 +3382,7 @@ public: String *qualified_classname = Copy(sym_name); String *nspace = getNSpace(); String *dirClassName = directorClassName(n); + String *smartptr_feature = Getattr(n, "feature:smartptr"); if (nspace) Insert(qualified_classname, 0, NewStringf("%s.", nspace)); @@ -3392,8 +3393,17 @@ public: Wrapper *code_wrap = NewWrapper(); Printf(code_wrap->def, "SWIGEXPORT void SWIGSTDCALL %s(void *objarg", wname); - Printf(code_wrap->code, " %s *obj = (%s *)objarg;\n", norm_name, norm_name); - Printf(code_wrap->code, " %s *director = dynamic_cast<%s *>(obj);\n", dirClassName, dirClassName); + if (Len(smartptr_feature)) { + Printf(code_wrap->code, " %s *obj = (%s *)objarg;\n", smartptr_feature, smartptr_feature); + 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 = 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 = dynamic_cast<%s *>(obj);\n", dirClassName, dirClassName); + } + // TODO: if statement not needed?? - Java too Printf(code_wrap->code, " if (director) {\n"); Printf(code_wrap->code, " director->swig_connect_director(");