swig -go: treat non-const references as pointers
Also clean up the handling of int* and int& to convert between the C type int and the Go type int, which are often different sizes. Fixes #2210
This commit is contained in:
parent
4499422308
commit
27bdbc1f05
4 changed files with 115 additions and 19 deletions
|
|
@ -14,6 +14,26 @@ func (p *GoMyClass) Adjust(m map[string]interface{}) wrap.GoRetStruct {
|
|||
return wrap.GoRetStruct{s}
|
||||
}
|
||||
|
||||
func (p *GoMyClass) S1(s string) {
|
||||
if s != "S1" {
|
||||
panic(s)
|
||||
}
|
||||
}
|
||||
|
||||
func (p *GoMyClass) S2(s *string) {
|
||||
if *s != "S2" {
|
||||
panic(s)
|
||||
}
|
||||
*s = "R2"
|
||||
}
|
||||
|
||||
func (p *GoMyClass) S3(s *string) {
|
||||
if *s != "S3" {
|
||||
panic(s)
|
||||
}
|
||||
*s = "R3"
|
||||
}
|
||||
|
||||
func main() {
|
||||
a := wrap.NewDirectorMyClass(&GoMyClass{})
|
||||
m := map[string]interface{}{
|
||||
|
|
@ -24,6 +44,18 @@ func main() {
|
|||
panic(s)
|
||||
}
|
||||
|
||||
a.S1("S1")
|
||||
str := "S2"
|
||||
a.S2(&str)
|
||||
if str != "R2" {
|
||||
panic(str)
|
||||
}
|
||||
str = "S3"
|
||||
a.S3(&str)
|
||||
if str != "R3" {
|
||||
panic(str)
|
||||
}
|
||||
|
||||
a = wrap.NewDirectorMyClass(nil)
|
||||
s = a.Adjust(m)
|
||||
if s.Str != `{"first":"second"}` {
|
||||
|
|
|
|||
|
|
@ -2,6 +2,8 @@
|
|||
|
||||
%module(directors="1") go_director_inout
|
||||
|
||||
%include <std_string.i>
|
||||
|
||||
%{
|
||||
#include <string>
|
||||
%}
|
||||
|
|
@ -108,6 +110,25 @@ type GoRetStruct struct {
|
|||
$1.str.assign($input.p, $input.n);
|
||||
%}
|
||||
|
||||
%typemap(directorin) std::string & (_gostring_ temp) {
|
||||
$input = &temp;
|
||||
temp.p = (char *) $1.data();
|
||||
temp.n = $1.size();
|
||||
}
|
||||
%typemap(directorargout) std::string & {
|
||||
_gostring_ *tmp = $input;
|
||||
$1.assign(tmp->p, tmp->p + tmp->n);
|
||||
}
|
||||
|
||||
%typemap(directorin) std::string * (_gostring_ temp) {
|
||||
$input = &temp;
|
||||
$input->p = (char *) $1->data();
|
||||
$input->n = $1->size();
|
||||
}
|
||||
%typemap(directorargout) std::string * {
|
||||
$1->assign($input->p, $input->p + $input->n);
|
||||
}
|
||||
|
||||
%feature("director") MyClass;
|
||||
|
||||
%inline
|
||||
|
|
@ -121,6 +142,10 @@ class MyClass {
|
|||
r.str = s.str;
|
||||
return r;
|
||||
}
|
||||
|
||||
virtual void S1(std::string s) = 0;
|
||||
virtual void S2(std::string& s) = 0;
|
||||
virtual void S3(std::string* s) = 0;
|
||||
};
|
||||
|
||||
%}
|
||||
|
|
|
|||
|
|
@ -453,9 +453,12 @@
|
|||
%}
|
||||
|
||||
%typemap(freearg)
|
||||
char *, char *&, char[ANY], char[]
|
||||
char *, char[ANY], char[]
|
||||
%{ free($1); %}
|
||||
|
||||
%typemap(freearg) char *&
|
||||
%{ free(*$1); %}
|
||||
|
||||
%typemap(out,fragment="AllocateString")
|
||||
char *, char *&, char[ANY], char[]
|
||||
%{ $result = Swig_AllocateString((char*)$1, $1 ? strlen((char*)$1) : 0); %}
|
||||
|
|
@ -520,6 +523,44 @@
|
|||
$2 = ($2_ltype)$input.n;
|
||||
%}
|
||||
|
||||
/* The int & type needs to convert to intgo. */
|
||||
|
||||
%typemap(gotype) int & "*int"
|
||||
|
||||
%typemap(in) int & (int e)
|
||||
%{
|
||||
e = (int)*$input;
|
||||
$1 = &e;
|
||||
%}
|
||||
|
||||
%typemap(out) int &
|
||||
%{ $result = new intgo(*$1); %}
|
||||
|
||||
%typemap(argout) int &
|
||||
%{ *$input = (intgo)e$argnum; %}
|
||||
|
||||
%typemap(goout) int & ""
|
||||
|
||||
%typemap(directorin) int & (intgo e)
|
||||
%{
|
||||
e = (intgo)$1;
|
||||
$input = &e;
|
||||
%}
|
||||
|
||||
%typemap(godirectorin) int & ""
|
||||
|
||||
%typemap(directorout) int &
|
||||
%{
|
||||
$*1_ltype f = ($*1_ltype)*$input;
|
||||
$result = ($1_ltype)&f;
|
||||
%}
|
||||
|
||||
%typemap(directorargout) int &
|
||||
%{ $1 = (int)*$input; %}
|
||||
|
||||
%typemap(argout) const int & ""
|
||||
%typemap(directorargout) const int & ""
|
||||
|
||||
/* Enums. We can't do the right thing for enums in typemap(gotype) so
|
||||
we deliberately don't define them. The right thing would be to
|
||||
capitalize the name. This is instead done in go.cxx. */
|
||||
|
|
@ -552,10 +593,7 @@
|
|||
%typemap(godirectorin) enum SWIGTYPE & ""
|
||||
|
||||
%typemap(directorout) enum SWIGTYPE &
|
||||
%{
|
||||
$*1_ltype f = ($*1_ltype)*$input;
|
||||
$result = ($1_ltype)&f;
|
||||
%}
|
||||
%{ $result = $input; %}
|
||||
|
||||
/* Arbitrary type. This is a type passed by value in the C/C++ code.
|
||||
We convert it to a pointer for the Go code. Note that all basic
|
||||
|
|
|
|||
|
|
@ -377,7 +377,7 @@ private:
|
|||
/* ---------------------------------------------------------------------
|
||||
* top()
|
||||
*
|
||||
* For 6g/8g, we are going to create the following files:
|
||||
* For gc, we are going to create the following files:
|
||||
*
|
||||
* 1) A .c or .cxx file compiled with gcc. This file will contain
|
||||
* function wrappers. Each wrapper will take a pointer to a
|
||||
|
|
@ -5284,7 +5284,7 @@ private:
|
|||
* gcCTypeForGoValue()
|
||||
*
|
||||
* Given a type, return the C/C++ type which will be used to catch
|
||||
* the value in Go. This is the 6g/8g version.
|
||||
* the value in Go. This is the gc version.
|
||||
* ---------------------------------------------------------------------- */
|
||||
|
||||
String *gcCTypeForGoValue(Node *n, SwigType *type, String *name) {
|
||||
|
|
@ -5293,7 +5293,19 @@ private:
|
|||
|
||||
String *tail = NewString("");
|
||||
SwigType *t = SwigType_typedef_resolve_all(type);
|
||||
if (!SwigType_isreference(t)) {
|
||||
bool is_const_ref = false;
|
||||
if (SwigType_isreference(t)) {
|
||||
SwigType* tt = Copy(t);
|
||||
SwigType_del_reference(tt);
|
||||
if (SwigType_isqualifier(tt)) {
|
||||
String* q = SwigType_parm(tt);
|
||||
if (Strcmp(q, "const") == 0) {
|
||||
is_const_ref = true;
|
||||
}
|
||||
}
|
||||
Delete(tt);
|
||||
}
|
||||
if (!is_const_ref) {
|
||||
while (Strncmp(gt, "*", 1) == 0) {
|
||||
Replace(gt, "*", "", DOH_REPLACE_FIRST);
|
||||
Printv(tail, "*", NULL);
|
||||
|
|
@ -5436,17 +5448,6 @@ private:
|
|||
return ret;
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
* gccgoCTypeForGoValue()
|
||||
*
|
||||
* Given a type, return the C/C++ type which will be used to catch
|
||||
* the value in Go. This is the gccgo version.
|
||||
* ---------------------------------------------------------------------- */
|
||||
|
||||
String *gccgoCTypeForGoValue(Node *n, SwigType *type, String *name) {
|
||||
return gcCTypeForGoValue(n, type, name);
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
* goTypeIsInterface
|
||||
*
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue