- by JG
            
            
            I've got a very large and mature C++ code base that I'm trying to use SWIG on to generate a C# interface for.  I cannot change the actual C++ code itself but we can use whatever SWIG offers in the way of extending/updating it.  I'm facing an issue where a function C++ is written as such:
A* SomeClass::next(A*)
The caller might do something like:
A* acurr = 0;
while( (acurr = sc->next(acurr)) != 0 ){
    if( acurr isoftype B ){
        B* b = (B*)a;
        ...do some stuff with b..
    }
    elseif( acurr isoftype C )
    ...
}
Essentially, iterating through a container elements that depending on their true type, do something different.  The SWIG generated C# layer for the "next" function unfortunately does the following:
return new A();
So the calling code in C# land cannot determine if the returned object is actually a derived class or not, it actually appears to always be the base class (which does make sense).  I've come across several solutions:
Use the %extend SWIG keyword to add a method on an object and ultimately call dynamic_cast.  The downside to this approach, as I see it, is that this requires you to know the inheritance hierarchy.  In my case it is rather huge and I see this is as a maintenance issue.
Use the %factory keyword to supply the method and the derived types and have SWIG automatically generate the dynamic_cast code.  This appears to be a better solution that the first, however upon a deeper look it still requires you to hunt down all the methods and all the possible derived types it could return.  Again, a huge maintenance issue.  I wish I had a doc link for this but I can't find one.  I found out about this functionality by looking through the example code that comes with SWIG.
Create a C# method to create an instance of the derived object and transfer the cPtr to the new instance.  While I consider this clumsy, it does work.  See an example below.
public static object castTo(object fromObj, Type toType)
{
    object retval = null;
BaseClass fromObj2 = fromObj as BaseClass;
HandleRef hr = BaseClass.getCPtr(fromObj2);
IntPtr cPtr = hr.Handle;
object toObj = Activator.CreateInstance(toType, cPtr, false);
// make sure it actually is what we think it is
if (fromObj.GetType().IsInstanceOfType(toObj))
{
    return toObj;
}
return retval;
}
Are these really the options?  And if I'm not willing to dig through all the existing functions and class derivations, then I'm left with #3?  Any help would be appreciated.