Better handling of return values. Some bugfixes.
git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/gsoc2008-maciekd@10618 626c5289-ae23-0410-ae9c-e8d60b6d4f22
This commit is contained in:
parent
ea05035844
commit
f74439e215
16 changed files with 208 additions and 58 deletions
|
|
@ -1,4 +1,4 @@
|
|||
/* File : example.cxx */
|
||||
/* File : example.c */
|
||||
|
||||
#include "example.h"
|
||||
#define M_PI 3.14159265358979323846
|
||||
|
|
@ -12,8 +12,7 @@ void Shape::move(double dx, double dy) {
|
|||
int Shape::nshapes = 0;
|
||||
|
||||
double Circle::area(void) {
|
||||
double xxx = M_PI*radius*radius;
|
||||
return xxx;
|
||||
return M_PI*radius*radius;
|
||||
}
|
||||
|
||||
double Circle::perimeter(void) {
|
||||
|
|
@ -27,4 +26,3 @@ double Square::area(void) {
|
|||
double Square::perimeter(void) {
|
||||
return 4*width;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
/* File : example.h */
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
class Shape {
|
||||
public:
|
||||
Shape() {
|
||||
|
|
@ -35,3 +33,7 @@ public:
|
|||
virtual double perimeter(void);
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -3,17 +3,35 @@
|
|||
#include "example_proxy.h"
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
Circle* pc = new_Circle(10.0);
|
||||
Square* ps = new_Square(10.0);
|
||||
printf("Creating some objects:\n");
|
||||
Circle* c = new_Circle(10);
|
||||
printf(" Created circle\n");
|
||||
Square* s = new_Square(10);
|
||||
printf(" Created square\n");
|
||||
|
||||
printf("Circle perim.=%f, area=%f\n", Circle_perimeter(pc), Circle_area(pc));
|
||||
printf("Square perim.=%f, area=%f\n", Square_perimeter(ps), Square_area(ps));
|
||||
printf("\nA total of %d shapes were created\n", 0);
|
||||
|
||||
printf("Circle pos.=(%f, %f)\n", Shape_get_x(pc), Shape_get_y(pc));
|
||||
Shape_move(pc, 5.0, -5.0);
|
||||
printf("After move pos.=(%f, %f)\n", Shape_get_x(pc), Shape_get_y(pc));
|
||||
|
||||
delete_Square(ps);
|
||||
delete_Circle(pc);
|
||||
printf("\nHere are some properties of the shapes:\n");
|
||||
Shape shapes[] = {c, s};
|
||||
int i;
|
||||
/*
|
||||
* TODO: support for virtual functions
|
||||
for (i = 0; i < 2; i++) {
|
||||
printf(" area = %f\n", Shape_area(shapes[i]));
|
||||
printf(" perimeter = %f\n", Shape_perimeter(shapes[i]));
|
||||
}
|
||||
*/
|
||||
|
||||
// call methods directly by now
|
||||
printf("Circle perim.=%f, area=%f\n", Circle_perimeter(c), Circle_area(c));
|
||||
printf("Square perim.=%f, area=%f\n", Square_perimeter(s), Square_area(s));
|
||||
|
||||
printf("\nGuess I'll clean up now\n");
|
||||
|
||||
delete_Square(s);
|
||||
delete_Circle(c);
|
||||
|
||||
printf("%d shapes remain\n", 0);
|
||||
printf("Goodbye\n");
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
TOP = ../..
|
||||
SWIG = $(TOP)/../preinst-swig -debug-module 4
|
||||
SWIG = $(TOP)/../preinst-swig -debug-module 4 > tree.txt
|
||||
CXXSRCS = example.cxx
|
||||
TARGET = example
|
||||
INTERFACE = example.i
|
||||
|
|
|
|||
|
|
@ -2,18 +2,18 @@
|
|||
|
||||
#include "example.h"
|
||||
|
||||
void foo_by_val(Bar foo) {
|
||||
foo.set(123);
|
||||
printf("inside foo_by_val: %d\n", foo.get());
|
||||
void foo_by_val(Bar bar) {
|
||||
bar.set(123);
|
||||
printf("inside foo_by_val: %d\n", bar.get());
|
||||
}
|
||||
|
||||
void foo_by_ref(Bar& foo) {
|
||||
foo.set(123);
|
||||
printf("inside foo_by_ref: %d\n", foo.get());
|
||||
void foo_by_ref(Bar& bar) {
|
||||
bar.set(123);
|
||||
printf("inside foo_by_ref: %d\n", bar.get());
|
||||
}
|
||||
|
||||
void foo_by_ptr(Bar* foo) {
|
||||
foo->set(123);
|
||||
printf("inside foo_by_ptr: %d\n", foo->get());
|
||||
void foo_by_ptr(Bar* bar) {
|
||||
bar->set(123);
|
||||
printf("inside foo_by_ptr: %d\n", bar->get());
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ void test(Bar * bar) {
|
|||
}
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
Bar * bar = new_Bar();
|
||||
Bar* bar = new_Bar();
|
||||
test(bar);
|
||||
foo_by_val(bar);
|
||||
test(bar);
|
||||
|
|
|
|||
14
Examples/c/return/Makefile
Normal file
14
Examples/c/return/Makefile
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
TOP = ../..
|
||||
SWIG = $(TOP)/../preinst-swig -debug-module 4 > tree.txt
|
||||
CXXSRCS = example.cxx
|
||||
TARGET = example
|
||||
INTERFACE = example.i
|
||||
MAIN = test.c
|
||||
|
||||
all::
|
||||
$(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \
|
||||
TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' MAIN='$(MAIN)' c_cpp
|
||||
|
||||
clean:
|
||||
rm -f *.o *.out *.so *.a *.dll *.exe *_wrap* *_proxy* *~
|
||||
|
||||
10
Examples/c/return/example.cxx
Normal file
10
Examples/c/return/example.cxx
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
#include "example.h"
|
||||
|
||||
Bar foo_ret_val() {
|
||||
return Bar();
|
||||
}
|
||||
|
||||
Bar* foo_ret_ptr(Bar* bar) {
|
||||
return bar;
|
||||
}
|
||||
|
||||
16
Examples/c/return/example.h
Normal file
16
Examples/c/return/example.h
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
#include <stdio.h>
|
||||
|
||||
class Bar {
|
||||
private:
|
||||
int x;
|
||||
public:
|
||||
Bar() : x(0) {}
|
||||
~Bar() {}
|
||||
void set(int x) { this->x = x; }
|
||||
int get() { return x; }
|
||||
};
|
||||
|
||||
Bar foo_ret_val();
|
||||
//Bar& foo_ret_ref(Bar* bar);
|
||||
Bar* foo_ret_ptr(Bar* bar);
|
||||
|
||||
8
Examples/c/return/example.i
Normal file
8
Examples/c/return/example.i
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
%module example
|
||||
|
||||
%{
|
||||
#include "example.h"
|
||||
%}
|
||||
|
||||
%include "example.h"
|
||||
|
||||
10
Examples/c/return/test.c
Normal file
10
Examples/c/return/test.c
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
#include <stdio.h>
|
||||
|
||||
#include "example_proxy.h"
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
Bar b = foo_ret_val();
|
||||
//Bar * bp = foo_ret_ptr(NULL);
|
||||
printf("x = %d\n", Bar_get(&b));
|
||||
}
|
||||
|
||||
|
|
@ -7,7 +7,7 @@ double *Foo_ptr = &Foo;
|
|||
char *my_str = "hello, world!";
|
||||
char *array_of_strs[] = { "one", "two" };
|
||||
|
||||
char *get_str(int i) {
|
||||
char *get_str(int i, void* ptr, float ff) {
|
||||
return array_of_strs[i];
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ extern double Foo;
|
|||
extern double *Foo_ptr;
|
||||
extern char *my_str;
|
||||
extern char **array_of_strs;
|
||||
extern char *get_str(int i);
|
||||
extern char *get_str(int i, void* ptr, float ff);
|
||||
extern int gcd(int x, int y);
|
||||
%}
|
||||
|
||||
|
|
|
|||
|
|
@ -9,8 +9,7 @@ int main(int argc, char **argv) {
|
|||
printf("Foo by ptr is \%f\n", *Foo_ptr);
|
||||
printf("my_str is: %s\n", my_str);
|
||||
printf("GCD(%d, %d)=%d\n", a, b, gcd(a, b));
|
||||
printf("array_of_strs contains %s and %s\n", get_str(0), get_str(1));
|
||||
printf("const Val = %d\n", Val);
|
||||
printf("array_of_strs contains %s and %s\n", get_str(0, 0, 0), get_str(1, 0, 0));
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
31
Lib/c/c.swg
31
Lib/c/c.swg
|
|
@ -5,18 +5,21 @@
|
|||
* c.swg
|
||||
* ----------------------------------------------------------------------------- */
|
||||
|
||||
%typemap(ctype) short "short"
|
||||
%typemap(ctype) int "int"
|
||||
%typemap(ctype) long "long"
|
||||
%typemap(ctype) char "char"
|
||||
%typemap(ctype) float "float"
|
||||
%typemap(ctype) double "double"
|
||||
%typemap(ctype) void, short, int, long, char, float, double "$1_type"
|
||||
%typemap(ctype) void*, short*, int*, long*, char*, float*, double* "$1_type"
|
||||
%typemap(ctype) bool "_Bool"
|
||||
%typemap(ctype) SWIGTYPE "struct $1_typeObj *"
|
||||
%typemap(ctype) SWIGTYPE * "struct $*1_typeObj *"
|
||||
%typemap(ctype) SWIGTYPE & "struct $*1_ltypeObj *"
|
||||
|
||||
%typemap(couttype) void, short, int, long, char, float, double "$1_type"
|
||||
%typemap(couttype) void*, short*, int*, long*, char*, float*, double* "$1_type"
|
||||
%typemap(couttype) bool "_Bool"
|
||||
%typemap(couttype) SWIGTYPE "struct $1_typeObj"
|
||||
%typemap(couttype) SWIGTYPE * "struct $*1_typeObj *"
|
||||
|
||||
%typemap(in) short, int, long, char, float, double, bool "$1 = $input;"
|
||||
%typemap(in) void*, short*, int*, long*, char*, float*, double*, bool* "$1 = $input;"
|
||||
|
||||
%typemap(in) SWIGTYPE {
|
||||
$1 = * ($1_type *) ($input->obj);
|
||||
|
|
@ -30,3 +33,19 @@
|
|||
$1 = ($*1_ltype *) $input->obj;
|
||||
}
|
||||
|
||||
%typemap(out) short, int, long, char, float, double, bool "$result = $1;"
|
||||
%typemap(out) void*, short*, int*, long*, char*, float*, double*, bool* "$result = $1;"
|
||||
%typemap(out) void ""
|
||||
|
||||
%typemap(out) SWIGTYPE {
|
||||
$result.obj = (void*) &$1;
|
||||
}
|
||||
|
||||
%typemap(out) SWIGTYPE * {
|
||||
$result->obj = (void*) $1;
|
||||
}
|
||||
|
||||
%typemap(out) SWIGTYPE & {
|
||||
// return by reference
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -231,18 +231,29 @@ public:
|
|||
* ------------------------------------------------------------------------ */
|
||||
|
||||
virtual int globalfunctionHandler(Node *n ) {
|
||||
String* action = NewString("");
|
||||
String* vis_hint = NewString("");
|
||||
String* return_type_str = SwigType_str(Getattr(n, "type"), 0);
|
||||
String* name = Getattr(n, "sym:name");
|
||||
ParmList* parms = Getattr(n, "parms");
|
||||
String* arg_list = NewString("");
|
||||
|
||||
Language::globalfunctionHandler(n);
|
||||
if (SwigType_type(Getattr(n, "type")) != T_VOID) {
|
||||
Printv(action, "$cppresult = (", SwigType_str(Getattr(n, "type"), 0), ") ", NIL);
|
||||
}
|
||||
Printv(action, Swig_cfunction_call(Getattr(n, "name"), parms), ";", NIL);
|
||||
Setattr(n, "wrap:action", action);
|
||||
|
||||
//Language::globalfunctionHandler(n);
|
||||
functionWrapper(n);
|
||||
|
||||
// add visibility hint for the compiler (do not override this symbol)
|
||||
Printv(vis_hint, "SWIGPROTECT(", return_type_str, " ", name, "(", ParmList_str(parms), ");)\n\n", NIL);
|
||||
Printv(f_wrappers, vis_hint, NIL);
|
||||
Printv(f_header, vis_hint, NIL);
|
||||
|
||||
Delete(arg_list);
|
||||
Delete(vis_hint);
|
||||
Delete(action);
|
||||
return SWIG_OK;
|
||||
}
|
||||
|
||||
|
|
@ -252,13 +263,14 @@ public:
|
|||
|
||||
virtual int functionWrapper(Node *n) {
|
||||
String *name = Getattr(n, "sym:name");
|
||||
SwigType *return_type = Getattr(n, "type");
|
||||
String *return_type_str = SwigType_str(return_type, 0);
|
||||
SwigType *type = Getattr(n, "type");
|
||||
SwigType *return_type = NewString("");
|
||||
String *arg_names = NewString("");
|
||||
ParmList *parms = Getattr(n, "parms");
|
||||
Parm *p;
|
||||
String* tm;
|
||||
String* proto = NewString("");
|
||||
bool is_void_return;
|
||||
|
||||
// create new function wrapper object
|
||||
Wrapper *wrapper = NewWrapper();
|
||||
|
|
@ -267,20 +279,42 @@ public:
|
|||
String *wname = Swig_name_wrapper(name);
|
||||
Setattr(n, "wrap:name", wname);
|
||||
|
||||
// create wrapper function prototype
|
||||
Printv(wrapper->def, "SWIGEXPORT ", return_type_str, " ", wname, "(", NIL);
|
||||
|
||||
// attach the standard typemaps
|
||||
emit_attach_parmmaps(parms, wrapper);
|
||||
Setattr(n, "wrap:parms", parms);
|
||||
|
||||
// set the return type
|
||||
if (Cmp(Getattr(n, "c:immutable"), "1") == 0) {
|
||||
Printv(return_type, SwigType_str(type, 0), NIL);
|
||||
}
|
||||
else if ((tm = Swig_typemap_lookup("couttype", n, "", 0))) {
|
||||
Printf(stdout, "FW = %s TM = %s\n", Getattr(n, "name"), tm);
|
||||
String *ctypeout = Getattr(n, "tmap:ctype:out"); // the type in the ctype typemap's out attribute overrides the type in the typemap
|
||||
if (ctypeout)
|
||||
tm = ctypeout;
|
||||
Printf(return_type, "%s", tm);
|
||||
}
|
||||
else {
|
||||
Swig_warning(WARN_C_TYPEMAP_CTYPE_UNDEF, input_file, line_number, "No ctype typemap defined for %s\n", SwigType_str(type, 0));
|
||||
}
|
||||
|
||||
// attach 'ctype' typemaps
|
||||
Swig_typemap_attach_parms("ctype", parms, wrapper);
|
||||
|
||||
Setattr(n, "wrap:parms", parms);
|
||||
|
||||
// emit variables for holding parameters
|
||||
emit_parameter_variables(parms, wrapper);
|
||||
|
||||
// is the function void?
|
||||
is_void_return = (Strcmp(return_type, "void") == 0);
|
||||
|
||||
// add variable for holding result of original function
|
||||
if (!is_void_return && (Cmp(Getattr(n, "c:immutable"), "1") != 0)) {
|
||||
Wrapper_add_localv(wrapper, "cppresult", SwigType_str(type, 0), "cppresult", NIL);
|
||||
}
|
||||
|
||||
// create wrapper function prototype
|
||||
Printv(wrapper->def, "SWIGEXPORT ", return_type, " ", wname, "(", NIL);
|
||||
|
||||
// prepare function definition
|
||||
int gencomma = 0;
|
||||
for (p = parms; p; ) {
|
||||
|
|
@ -297,6 +331,7 @@ public:
|
|||
|
||||
Printf(arg_name, "c%s", lname);
|
||||
|
||||
// set the appropriate type for parameter
|
||||
if (Cmp(Getattr(p, "c:immutable"), "1") == 0) {
|
||||
Printv(c_parm_type, SwigType_str(type, 0), NIL);
|
||||
}
|
||||
|
|
@ -316,14 +351,17 @@ public:
|
|||
Printv(shadow_parm_type, c_parm_type, NIL);
|
||||
}
|
||||
|
||||
Replaceall(c_parm_type, "::", "_");
|
||||
|
||||
Printv(arg_names, gencomma ? ", " : "", Getattr(p, "name"), NIL);
|
||||
Printv(wrapper->def, gencomma ? ", " : "", c_parm_type, " ", arg_name, NIL);
|
||||
Printv(proto, gencomma ? ", " : "", shadow_parm_type, " ", Getattr(p, "name"), NIL);
|
||||
gencomma = 1;
|
||||
|
||||
// apply typemaps for input parameter
|
||||
if ((tm = Getattr(p, "tmap:in"))) {
|
||||
if (Cmp(Getattr(p, "c:immutable"), "1") == 0) {
|
||||
// FIXME
|
||||
// FIXME: should work as typemaps for basic types
|
||||
Printv(wrapper->code, lname, " = ", arg_name, ";\n", NIL);
|
||||
}
|
||||
else {
|
||||
|
|
@ -344,13 +382,30 @@ public:
|
|||
|
||||
Printf(wrapper->def, ") {");
|
||||
|
||||
// declare wrapper function local variables
|
||||
// emit variable for holding function return value
|
||||
emit_return_variable(n, return_type, wrapper);
|
||||
|
||||
// emit action code
|
||||
String *action = emit_action(n);
|
||||
Append(wrapper->code, action);
|
||||
if (return_type && Strcmp(return_type, "void") != 0)
|
||||
Replaceall(action, "$cppresult", "cppresult");
|
||||
|
||||
// emit output typemap if needed
|
||||
if (!is_void_return && (Cmp(Getattr(n, "c:immutable"), "1") != 0)) {
|
||||
if ((tm = Swig_typemap_lookup_out("out", n, "cppresult", wrapper, action))) {
|
||||
Replaceall(tm, "$result", "result");
|
||||
Printf(wrapper->code, "%s", tm);
|
||||
if (Len(tm))
|
||||
Printf(wrapper->code, "\n");
|
||||
}
|
||||
else {
|
||||
Swig_warning(WARN_TYPEMAP_OUT_UNDEF, input_file, line_number, "Unable to use return type %s in function %s.\n", SwigType_str(type, 0), Getattr(n, "name"));
|
||||
}
|
||||
}
|
||||
else {
|
||||
Append(wrapper->code, action);
|
||||
}
|
||||
|
||||
if (!is_void_return)
|
||||
Append(wrapper->code, "return result;\n");
|
||||
|
||||
Append(wrapper->code, "}\n");
|
||||
|
|
@ -361,12 +416,12 @@ public:
|
|||
// use shadow-type for return type if supplied
|
||||
SwigType* shadow_type = Getattr(n, "c:stype");
|
||||
if (shadow_type) {
|
||||
return_type_str = SwigType_str(shadow_type, 0);
|
||||
return_type = SwigType_str(shadow_type, 0);
|
||||
}
|
||||
|
||||
// emit proxy functions prototypes
|
||||
Printv(f_shadow_code_init, "extern ", return_type_str, " ", wname, "(", proto, ");\n", NIL);
|
||||
Printv(f_shadow_code_body, return_type_str, " ", name, "(", proto, ") {\n", NIL);
|
||||
Printv(f_shadow_code_init, "extern ", return_type, " ", wname, "(", proto, ");\n", NIL);
|
||||
Printv(f_shadow_code_body, return_type, " ", name, "(", proto, ") {\n", NIL);
|
||||
|
||||
// handle 'prepend' feature
|
||||
String *prepend_str = Getattr(n, "feature:prepend");
|
||||
|
|
@ -396,15 +451,15 @@ public:
|
|||
Printv(f_shadow_code_body, "}\n", NIL);
|
||||
|
||||
// add function declaration to the proxy header file
|
||||
Printv(f_shadow_header, return_type_str, " ", name, "(", proto, ");\n");
|
||||
Printv(f_shadow_header, return_type, " ", name, "(", proto, ");\n");
|
||||
}
|
||||
|
||||
// cleanup
|
||||
Delete(proto);
|
||||
Delete(arg_names);
|
||||
Delete(wname);
|
||||
Delete(return_type);
|
||||
DelWrapper(wrapper);
|
||||
|
||||
return SWIG_OK;
|
||||
}
|
||||
|
||||
|
|
@ -423,7 +478,7 @@ public:
|
|||
|
||||
// declare it in the proxy header
|
||||
if (shadow_flag) {
|
||||
Printv(f_shadow_header, "\ntypedef ", sobj_name, " ", name, ";\n\n", NIL);
|
||||
Printv(f_shadow_header, "\ntypedef ", sobj_name, " {\n void* obj;\n} ", name, ";\n\n", NIL);
|
||||
}
|
||||
|
||||
Delete(sobj_name);
|
||||
|
|
@ -480,7 +535,7 @@ public:
|
|||
arg_call_lnames = empty_string;
|
||||
|
||||
// generate action code
|
||||
Printv(code, (Strcmp(Getattr(n, "type"), "void") != 0) ? "result = " : "", NIL);
|
||||
Printv(code, (Strcmp(Getattr(n, "type"), "void") != 0) ? "$cppresult = " : "", NIL);
|
||||
Printv(code, "((", classname, "*) arg1->obj)->", name, "(", arg_call_lnames, ");\n", NIL);
|
||||
Setattr(n, "wrap:action", code);
|
||||
|
||||
|
|
@ -548,7 +603,7 @@ public:
|
|||
Setattr(n, "parms", p);
|
||||
|
||||
// generate action code
|
||||
Printv(code, "result = ((", classname, "*) arg1->obj)->", name, ";\n", NIL);
|
||||
Printv(code, "$cppresult = ((", classname, "*) arg1->obj)->", name, ";\n", NIL);
|
||||
Setattr(n, "wrap:action", code);
|
||||
|
||||
// modify method name
|
||||
|
|
@ -610,6 +665,7 @@ public:
|
|||
ctype = Copy(sobj_name);
|
||||
SwigType_add_pointer(ctype);
|
||||
Setattr(n, "type", ctype);
|
||||
Setattr(n, "c:immutable", "1");
|
||||
stype = Copy(name);
|
||||
SwigType_add_pointer(stype);
|
||||
Setattr(n, "c:stype", stype);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue