From: William S F. <ws...@fu...> - 2005-12-21 22:41:07
|
Olly Betts wrote: > C# supports operator overloading (in particular operator++). Is it > possible to wrap a C++ class which overloads operator++ in C# such > that ++ can be used on the wrapped class? > > If I try to wrap it directly by just including it in the .i file, I get: > > xapian.i:366: Warning(503): Can't wrap 'operator ++' unless renamed to a valid identifier. > > The manual says: > > Some language modules already know how to automatically handle > certain operators (mapping them into operators in the target > language). However, the underlying implementation of this is > really managed in a very general way using the %rename > directive. For example, in Python a declaration similar to this > is used: > > %rename(__add__) Complex::operator+; > > But this is a syntax error: > > %rename(operator++) operator++; > > So it doesn't look like this can be supported this way for C#. Is there > any way to make this work? It seems unnatural for C# to have to use > "foo.inc()" when C++ uses "++foo". > You can get SWIG to parse unusual names, such as: %rename("operator++") operator ++; However, it doesn't solve the problem as the new name must be a valid C symbol (for the PInvoke layer) so you still get the warning about not being a valid symbol name. Changing SWIG to have different symbol names for the proxy class and the PInvoke layer isn't a 5 minute job, plus there are other problems with operators. The C++ way of declaring operators does not match the way that C# wants them declared. For example: // C++ class Op{ public: Op& operator++(){++i; return *this;} // prefix ++ Op& operator++(int){i++; return *this;} // postfix ++ } // C# public class Op { public static Op operator++(Op op) { return op.operator_plus_plus(); } } There is no differentiation between prefix and postfix in C#. Also in C# the method is static and it takes different parameters. So morphing the C++ declaration into a C# one isn't so natural. The easiest approach is to just add in the correct C# declaration into your C# class as such: %rename(operator_plus_plus) operator ++; %typemap(cscode) Op %{ public static Op operator++(Op op) { return op.operator_plus_plus(); } %} You should be able to make the generated/renamed function private with: %csmethodmodifiers operator++ "private"; but %feature doesn't seem to be working with operators. We'll have to fix that one. William |