William S Fulton
2017-07-01 11:03:25 UTC
On 25 June 2017 at 19:32, Georgios Petasis via Swig-user <
%module example
%inline %{
struct CDM_SpanSet {};
struct CDM_Annotation {};
const char * AddSpan(CDM_SpanSet spanset, int start, int end) { return
"AddSpan(CDM_SpanSet...)"; }
const char * AddSpan(CDM_Annotation annotation, int start, int end) {
return "AddSpan(CDM_Annotation...)"; }
%}
and run with the option to show the typemaps used and grep to filter out
for the annotation parameter:
$ swig -tcl8 -c++ -debug-tmused -o example_wrap.cxx example.i | grep
annotation
example.i:6: Typemap for CDM_SpanSet spanset (in) : %typemap(in) SWIGTYPE
example.i:6: Typemap for CDM_SpanSet spanset (typecheck) :
%typemap(typecheck) SWIGTYPE
It is quite clear the typecheck typemap is used, and if you look in the
generated c++ code you should find code that does the type checking (see
the _wrap_AddSpan function). Take the default SWIGTYPE typemap (which you
can find if you run swig -E and look for it). If you add it into your
interface file before the use of CDM_Spanet and change it to target the
CDM_SpanSet type, then you can modify and enhance it as you like:
%typemap(typecheck,precedence= 0 ,noblock=1) CDM_SpanSet {
void *vptr = 0;
int res = SWIG_ConvertPtr($input, &vptr, $&descriptor, 0);
$1 = SWIG_CheckState(res);
// add in your custom modifications to try convert $input to "{}" if the
above fails
}
If you run with -debug-tmused again, it will use the more specific typemap
above. Please have a good look at http://swig.org/Doc3.0/Typemaps.html.
William
Hi all,
I have two C++ classes (SpanSet & Annotation), which I expose as C++
classes in Tcl through swig, but also through an API that is closer to C
(although still I am using overloading). In this API, I cast pointer to
class objects in C structs (CDM_SpanSet, CDM_Annotation).
A: AddSpan(CDM_SpanSet, const CDM_Span);
B: AddSpan(CDM_SpanSet, int start, int end)
C: AddSpan(CDM_Annotation, const CDM_Span);
D: AddSpan(CDM_Annotation, int start, int end);
If there are two args, if 1st arg is SWIGTYPE_p_CDM_SpanSet_t, call A,
else C.
If there are 3 args, if 1st arg is SWIGTYPE_p_CDM_SpanSet_t call B, else D.
What is the problem: I have defined in/out templates, which actually
interface better these values with Tcl objects.
With my templates, a string representation of the pointer is never
returned: the pointers are placed in Tcl objects that hold this pointer.
And my code can even derive a pointer from a Tcl representation.
So, to a non-overloaded AddSpan(CDM_SpanSet, ...), CDM_SpanSet can be any
1: A pointer, like _20dc240200000000_p_ELEP__CDM__SpanSet (i.e. created
from CDM::SpanSet, the "class" interface swig provides).
2: A Tcl object, like "{}" (actually a nested Tcl list). If it is an
object that holds a SpanSet object, it is converted.
3: A tcl object of type SpanSet, returned from another API call (like
CreateSpanSet).
The problem is that the code that swig generates, can handle only case 1.
My input templates are ignored when the function that will handle
overloading is generated.
Looking at the documentation, it seems I have to also define a typecheck
template.
But Tcl generator does not use the typecheck templates
The typecheck typemaps are used. To demonstrate, I use this:I have two C++ classes (SpanSet & Annotation), which I expose as C++
classes in Tcl through swig, but also through an API that is closer to C
(although still I am using overloading). In this API, I cast pointer to
class objects in C structs (CDM_SpanSet, CDM_Annotation).
A: AddSpan(CDM_SpanSet, const CDM_Span);
B: AddSpan(CDM_SpanSet, int start, int end)
C: AddSpan(CDM_Annotation, const CDM_Span);
D: AddSpan(CDM_Annotation, int start, int end);
If there are two args, if 1st arg is SWIGTYPE_p_CDM_SpanSet_t, call A,
else C.
If there are 3 args, if 1st arg is SWIGTYPE_p_CDM_SpanSet_t call B, else D.
What is the problem: I have defined in/out templates, which actually
interface better these values with Tcl objects.
With my templates, a string representation of the pointer is never
returned: the pointers are placed in Tcl objects that hold this pointer.
And my code can even derive a pointer from a Tcl representation.
So, to a non-overloaded AddSpan(CDM_SpanSet, ...), CDM_SpanSet can be any
1: A pointer, like _20dc240200000000_p_ELEP__CDM__SpanSet (i.e. created
from CDM::SpanSet, the "class" interface swig provides).
2: A Tcl object, like "{}" (actually a nested Tcl list). If it is an
object that holds a SpanSet object, it is converted.
3: A tcl object of type SpanSet, returned from another API call (like
CreateSpanSet).
The problem is that the code that swig generates, can handle only case 1.
My input templates are ignored when the function that will handle
overloading is generated.
Looking at the documentation, it seems I have to also define a typecheck
template.
But Tcl generator does not use the typecheck templates
%module example
%inline %{
struct CDM_SpanSet {};
struct CDM_Annotation {};
const char * AddSpan(CDM_SpanSet spanset, int start, int end) { return
"AddSpan(CDM_SpanSet...)"; }
const char * AddSpan(CDM_Annotation annotation, int start, int end) {
return "AddSpan(CDM_Annotation...)"; }
%}
and run with the option to show the typemaps used and grep to filter out
for the annotation parameter:
$ swig -tcl8 -c++ -debug-tmused -o example_wrap.cxx example.i | grep
annotation
example.i:6: Typemap for CDM_SpanSet spanset (in) : %typemap(in) SWIGTYPE
example.i:6: Typemap for CDM_SpanSet spanset (typecheck) :
%typemap(typecheck) SWIGTYPE
It is quite clear the typecheck typemap is used, and if you look in the
generated c++ code you should find code that does the type checking (see
the _wrap_AddSpan function). Take the default SWIGTYPE typemap (which you
can find if you run swig -E and look for it). If you add it into your
interface file before the use of CDM_Spanet and change it to target the
CDM_SpanSet type, then you can modify and enhance it as you like:
%typemap(typecheck,precedence= 0 ,noblock=1) CDM_SpanSet {
void *vptr = 0;
int res = SWIG_ConvertPtr($input, &vptr, $&descriptor, 0);
$1 = SWIG_CheckState(res);
// add in your custom modifications to try convert $input to "{}" if the
above fails
}
If you run with -debug-tmused again, it will use the more specific typemap
above. Please have a good look at http://swig.org/Doc3.0/Typemaps.html.
William