From 568607c5ea1479084276da13bb867092741f31c8 Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Fri, 16 Jul 2010 18:45:22 +0000 Subject: [PATCH] Fix wrapping of function pointers and member function pointers when the function returns by reference git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@12157 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- CHANGES.current | 4 +++ Examples/test-suite/common.mk | 1 + Examples/test-suite/funcptr_cpp.i | 16 ++++++++++++ Examples/test-suite/member_pointer.i | 26 +++++++++++++++++++ .../test-suite/python/funcptr_cpp_runme.py | 9 +++++++ .../test-suite/python/member_pointer_runme.py | 3 +++ Source/Swig/stype.c | 12 ++++++--- 7 files changed, 67 insertions(+), 4 deletions(-) create mode 100644 Examples/test-suite/funcptr_cpp.i create mode 100644 Examples/test-suite/python/funcptr_cpp_runme.py diff --git a/CHANGES.current b/CHANGES.current index 510ec0dfe..63af7206d 100644 --- a/CHANGES.current +++ b/CHANGES.current @@ -5,6 +5,10 @@ See the RELEASENOTES file for a summary of changes in each release. Version 2.0.1 (in progress) =========================== +2010-07-16: wsfulton + Fix wrapping of function pointers and member function pointers when the function + returns by reference. + 2010-07-08: wsfulton Fix #3024875 - shared_ptr of classes with non-public destructors. This also fixes the "unref" feature when used on classes with non-public destructors. diff --git a/Examples/test-suite/common.mk b/Examples/test-suite/common.mk index 5033f1957..1463ce63c 100644 --- a/Examples/test-suite/common.mk +++ b/Examples/test-suite/common.mk @@ -201,6 +201,7 @@ CPP_TEST_CASES += \ features \ fragments \ friends \ + funcptr_cpp \ fvirtual \ global_namespace \ global_ns_arg \ diff --git a/Examples/test-suite/funcptr_cpp.i b/Examples/test-suite/funcptr_cpp.i new file mode 100644 index 000000000..d59f970ee --- /dev/null +++ b/Examples/test-suite/funcptr_cpp.i @@ -0,0 +1,16 @@ +%module funcptr_cpp + +%inline %{ + +int addByValue(const int &a, int b) { return a+b; } +int * addByPointer(const int &a, int b) { static int val; val = a+b; return &val; } +int & addByReference(const int &a, int b) { static int val; val = a+b; return val; } + +int call1(int (*d)(const int &, int), int a, int b) { return d(a, b); } +int call2(int * (*d)(const int &, int), int a, int b) { return *d(a, b); } +int call3(int & (*d)(const int &, int), int a, int b) { return d(a, b); } +%} + +%constant int (*ADD_BY_VALUE)(const int &, int) = addByValue; +%constant int * (*ADD_BY_POINTER)(const int &, int) = addByPointer; +%constant int & (*ADD_BY_REFERENCE)(const int &, int) = addByReference; diff --git a/Examples/test-suite/member_pointer.i b/Examples/test-suite/member_pointer.i index f03528cd5..d9d5cbef5 100644 --- a/Examples/test-suite/member_pointer.i +++ b/Examples/test-suite/member_pointer.i @@ -99,3 +99,29 @@ double (Shape::*perimetervar)(void) = &Shape::perimeter; %constant double (Shape::*PERIMPT)(void) = &Shape::perimeter; %constant double (Shape::*NULLPT)(void) = 0; +/* +%inline %{ + struct Funktions { + void retByRef(int & (*d)(double)) {} + }; + void byRef(int & (Funktions::*d)(double)) {} +%} +*/ + +%inline %{ + +struct Funktions { + int addByValue(const int &a, int b) { return a+b; } + int * addByPointer(const int &a, int b) { static int val; val = a+b; return &val; } + int & addByReference(const int &a, int b) { static int val; val = a+b; return val; } +}; + +int call1(int (Funktions::*d)(const int &, int), int a, int b) { Funktions f; return (f.*d)(a, b); } +int call2(int * (Funktions::*d)(const int &, int), int a, int b) { Funktions f; return *(f.*d)(a, b); } +int call3(int & (Funktions::*d)(const int &, int), int a, int b) { Funktions f; return (f.*d)(a, b); } +%} + +%constant int (Funktions::*ADD_BY_VALUE)(const int &, int) = &Funktions::addByValue; +%constant int * (Funktions::*ADD_BY_POINTER)(const int &, int) = &Funktions::addByPointer; +%constant int & (Funktions::*ADD_BY_REFERENCE)(const int &, int) = &Funktions::addByReference; + diff --git a/Examples/test-suite/python/funcptr_cpp_runme.py b/Examples/test-suite/python/funcptr_cpp_runme.py new file mode 100644 index 000000000..ae8616e94 --- /dev/null +++ b/Examples/test-suite/python/funcptr_cpp_runme.py @@ -0,0 +1,9 @@ +from funcptr_cpp import * + +if call1(ADD_BY_VALUE, 10, 11) != 21: + raise RuntimeError +if call2(ADD_BY_POINTER, 12, 13) != 25: + raise RuntimeError +if call3(ADD_BY_REFERENCE, 14, 15) != 29: + raise RuntimeError + diff --git a/Examples/test-suite/python/member_pointer_runme.py b/Examples/test-suite/python/member_pointer_runme.py index 27e7a483d..3d68e916d 100644 --- a/Examples/test-suite/python/member_pointer_runme.py +++ b/Examples/test-suite/python/member_pointer_runme.py @@ -41,3 +41,6 @@ memberPtr = NULLPT check ("Square area ", 100.0, do_op(s,AREAPT)) check ("Square perim", 40.0, do_op(s,PERIMPT)) +check ("Add by value", 3, call1(ADD_BY_VALUE, 1, 2)) +check ("Add by pointer", 7, call2(ADD_BY_POINTER, 3, 4)) +check ("Add by reference", 11, call3(ADD_BY_REFERENCE, 5, 6)) diff --git a/Source/Swig/stype.c b/Source/Swig/stype.c index c984d639b..dd2aea688 100644 --- a/Source/Swig/stype.c +++ b/Source/Swig/stype.c @@ -735,6 +735,7 @@ String *SwigType_rcaststr(SwigType *s, const_String_or_char_ptr name) { int clear = 1; int firstarray = 1; int isreference = 0; + int isfunction = 0; int isarray = 0; result = NewStringEmpty(); @@ -835,6 +836,7 @@ String *SwigType_rcaststr(SwigType *s, const_String_or_char_ptr name) { } Append(result, ")"); Delete(parms); + isfunction = 1; } else { String *bs = SwigType_namestr(element); Insert(result, 0, " "); @@ -850,10 +852,12 @@ String *SwigType_rcaststr(SwigType *s, const_String_or_char_ptr name) { cast = NewStringf("(%s)", result); } if (name) { - if (isreference) { - if (isarray) - Clear(cast); - Append(cast, "*"); + if (!isfunction) { + if (isreference) { + if (isarray) + Clear(cast); + Append(cast, "*"); + } } Append(cast, name); }