VTK/Wrapping hints: Difference between revisions
(16 intermediate revisions by the same user not shown) | |||
Line 25: | Line 25: | ||
Once this macro is defined, we can use it in our method declarations. | Once this macro is defined, we can use it in our method declarations. | ||
The hint attributes that VTK provides are as follows: | The only hint attributes that VTK provides right now are as follows: | ||
===[[<nowiki />vtk::newinstance]]=== | ===[[<nowiki />vtk::newinstance]]=== | ||
Line 36: | Line 36: | ||
</pre> | </pre> | ||
===[[<nowiki />vtk:: | ===[[<nowiki />vtk::zerocopy]]=== | ||
This indicates that a | This indicates that a pointer parameter must be passed directly, without any copying of the data that it points to. For Python, it indicates that the "buffer" interface will be used for the parameter, rather than the "sequence" interface that is usually used for pointers and arrays. | ||
<pre> | <pre> | ||
void SetArray(VTK_ZEROCOPY float *buffer, vtkIdType size); | |||
</pre> | </pre> | ||
===[[<nowiki />vtk::sizehint(expression)]]=== | |||
===[[<nowiki />vtk::sizehint(arg, expression)]]=== | |||
These indicates that a pointer type, such as 'float *', points to an array of 'expression' values, where 'expression' is a C++ expression that evaluates to an integer. | |||
<pre> | |||
// declare the size of the return value | |||
double* GetPoint() VTK_SIZEHINT(3); | |||
// a hint can be applied to any of the parameters (and multiple sizehints are allowed, too) | |||
void InsertNextCell(vtkIdType n, vtkidType* ptIds) VTK_SIZEHINT(ptIds, n); | |||
// "this" is understood to be a pointer to the object ("this->" can be omitted) | |||
class vtkDataArray | |||
{ | |||
vtkIdType GetNumberOfComponents(); | |||
void SetTuple(const double* tuple) | |||
VTK_SIZEHINT(tuple, this->GetNumberOfComponents()); | |||
} | |||
</pre> | |||
===[[<nowiki />vtk::expects(condition)]]=== | |||
This indicates that 'condition' is a precondition for calling a method. If the condition is not met, then a ValueError exception is raised in Python and the C++ method is not called. Any number of 'expects' hints are allowed, they are checked in the order in which they appear. | |||
<pre> | |||
class vtkDataArray | |||
{ | |||
vtkIdType GetNumberOfTuples(); | |||
void SetTuple(i, const double* tuple) | |||
VTK_EXPECTS(i < GetNumberOfTuples()) // condition #1 | |||
VTK_EXPECTS(tuple != nullptr); // condition #2 | |||
} | |||
</pre> | |||
==Proposed hints== | |||
These are hints that aren't supported by the wrappers yet, and might never be supported. | |||
===[[<nowiki />vtk::nevernull]]=== | ===[[<nowiki />vtk::nevernull]]=== | ||
Line 50: | Line 90: | ||
<pre> | <pre> | ||
void SetName(VTK_NEVERNULL const char *name); | void SetName(VTK_NEVERNULL const char *name); | ||
</pre> | |||
===[[<nowiki />vtk::unterminated]]=== | |||
For "char *" or "const char *", this hint indicates that the string might not be terminated. | |||
<pre> | |||
VTK_UNTERMINATED | |||
const char* GetData(); | |||
</pre> | </pre> | ||
===[[<nowiki />vtk::takeref(method)]]=== | ===[[<nowiki />vtk::takeref(method)]]=== | ||
For a return value, this indicates that the caller should take ownership of the object and dispose of it by the given method, which can be "delete", "delete []", "free | For a return value, this indicates that the caller should take ownership of the object and dispose of it by the given method, which can be "delete", "delete []", "free", etc. For a parameter, this indicates that the method will dispose of the object by the given method, and that the caller is no longer responsible for deletion. | ||
<pre> | <pre> | ||
Line 62: | Line 110: | ||
char* CreateName(); | char* CreateName(); | ||
</pre> | </pre> | ||
===[[<nowiki />vtk::wrapexclude]]=== | |||
This hint indicates that a class or method should not be wrapped. |
Latest revision as of 15:59, 25 January 2019
Sometimes the VTK wrappers need a little help in order to properly wrap certain C++ methods. Most often, this occurs when a method takes or returns a pointer. Some examples of the "unknowns" for a pointer that might have to be hinted are:
- Does the API allow the pointer to be NULL?
- Does it point to a single object, or an array?
- If an array, what is the size of the array?
- Will 'delete' or 'free()' have to be called to free the memory?
- If the pointer is 'char *', is it null-terminated? Is it ASCII, utf-8, or latin1?
Hinting with attributes
C++11 introduced attributes to provide hints for the compiler, such as the [[noreturn]] attribute to indicate that a method will never return:
[[noreturn]] void exit(int status);
We are allowed to define our own attributes, as long as we define a unique namespace, e.g. [[vtk::name]]. However, we don't want the attributes to be be "naked" in the code, because that would break pre-C++11 compilers. Instead, we conditionally define the attributes within macros (this is done within vtkSetGet.h, as for most VTK macros).
#ifdef __VTK_WRAP__ #define VTK_NEWINSTANCE [[vtk::newinstance]] #else #define VTK_NEWINSTANCE #endif
Once this macro is defined, we can use it in our method declarations.
The only hint attributes that VTK provides right now are as follows:
[[vtk::newinstance]]
This indicates that the method returns a vtkObject that has just been created, and the caller must call Delete() on the returned value when done with it.
VTK_NEWINSTANCE vtkObjectBase* NewInstance();
[[vtk::zerocopy]]
This indicates that a pointer parameter must be passed directly, without any copying of the data that it points to. For Python, it indicates that the "buffer" interface will be used for the parameter, rather than the "sequence" interface that is usually used for pointers and arrays.
void SetArray(VTK_ZEROCOPY float *buffer, vtkIdType size);
[[vtk::sizehint(expression)]]
[[vtk::sizehint(arg, expression)]]
These indicates that a pointer type, such as 'float *', points to an array of 'expression' values, where 'expression' is a C++ expression that evaluates to an integer.
// declare the size of the return value double* GetPoint() VTK_SIZEHINT(3); // a hint can be applied to any of the parameters (and multiple sizehints are allowed, too) void InsertNextCell(vtkIdType n, vtkidType* ptIds) VTK_SIZEHINT(ptIds, n); // "this" is understood to be a pointer to the object ("this->" can be omitted) class vtkDataArray { vtkIdType GetNumberOfComponents(); void SetTuple(const double* tuple) VTK_SIZEHINT(tuple, this->GetNumberOfComponents()); }
[[vtk::expects(condition)]]
This indicates that 'condition' is a precondition for calling a method. If the condition is not met, then a ValueError exception is raised in Python and the C++ method is not called. Any number of 'expects' hints are allowed, they are checked in the order in which they appear.
class vtkDataArray { vtkIdType GetNumberOfTuples(); void SetTuple(i, const double* tuple) VTK_EXPECTS(i < GetNumberOfTuples()) // condition #1 VTK_EXPECTS(tuple != nullptr); // condition #2 }
Proposed hints
These are hints that aren't supported by the wrappers yet, and might never be supported.
[[vtk::nevernull]]
This indicates that a pointer will never be null (if returned), or must never be null (if passed as a parameter).
void SetName(VTK_NEVERNULL const char *name);
[[vtk::unterminated]]
For "char *" or "const char *", this hint indicates that the string might not be terminated.
VTK_UNTERMINATED const char* GetData();
[[vtk::takeref(method)]]
For a return value, this indicates that the caller should take ownership of the object and dispose of it by the given method, which can be "delete", "delete []", "free", etc. For a parameter, this indicates that the method will dispose of the object by the given method, and that the caller is no longer responsible for deletion.
VTK_TAKEREF(delete[]) char* CreateName();
[[vtk::wrapexclude]]
This hint indicates that a class or method should not be wrapped.