From: jiangzhiyang <ja...@gm...> - 2008-05-27 11:15:37
|
William S Fulton 写道: > jiangzhiyang wrote: >> William S Fulton wrote: >>> jiangzhiyang wrote: >>>> Hi all >>>> I had written a application for this year's GSOC , my proposal is >>>> about >>>> "Better Multiple Inheritance Support",unfortunately i am not >>>> selected,and William said, he will help me even though i am not a >>>> formal >>>> student of GSOC, i think it is a good opportunity to be involved in >>>> the >>>> open source community,also i would like to do something for the >>>> SWIG for >>>> i am a user of SWIG. what i want to do is as follow: >>>> Now there is not a complete support for multiple inheritance when >>>> wrapping c++ code for java and c# in SWIG, because there is no direct >>>> multiple inheritance mechanism in java and c#, it can be implemented >>>> through the interfaces in java and c#, some sample c++ codes like >>>> this: >>>> //cpp >>>> struct CBase1 { >>>> virtual int foo1(){ >>>> return 1; >>>> } >>>> virtual ~CBase1(){ >>>> } >>>> }; >>>> struct CBase2{ >>>> virtual int foo2(){ >>>> return 2; >>>> } >>>> virtual ~CBase2(){ >>>> } >>>> }; >>>> struct ABase1{ >>>> virtual int bar1()=0; >>>> virtual ~ABase1(){ >>>> } >>>> }; >>>> >>>> struct Derived1 : CBase1,CBase2{ >>>> virtual int foo1(){ >>>> return 3; >>>> } >>>> virtual int foo2(){ >>>> return 4; >>>> } >>>> }; >>>> struct Derived2:CBase1,ABase1{ >>>> virtual int bar1(){ >>>> return 5; >>>> } >>>> virtual int foo1(){ >>>> return 6; >>>> } >>>> >>>> }; >>>> struct Derived3:CBase1,CBase2,ABase1{ >>>> virtual int foo1(){ >>>> return 7; >>>> } >>>> virtual int foo2(){ >>>> return 8; >>>> } >>>> virtual int bar1(){ >>>> return 9; >>>> } >>>> virtual ABase1* clone(){ >>>> return new Derived3(*this); >>>> } >>>> }; >>>> For supporting multiple inheritance completely ,firstly a directive >>>> like >>>> "%feature("interface")" is needed, it is used to show which class >>>> in c++ >>>> can be implemented as interface in java or c#.For the aboved code : >>>> >>>> // a interface file for multiple interitace >>>> %feature("interface") CBase1,CBase2,ABase1 >>>> >>> Actually the %feature syntax requires you to write this in 3 lines: >>> %feature("interface") CBase1; >>> %feature("interface") CBase2; >>> %feature("interface") ABase1; >>> >> I am sorry about my poor swig syntax. >>>> it shows that "CBase1,CBase2,ABase1" can be interfaces in java or c#. >>>> Some rules about the %feature("interface") like this: >>>> 1.About What does the definition of interface look like? >>>> I) If a derived class has two or more base classes, every base >>>> class may >>>> be implements as a interface of java and a concrete class of java >>>> if it >>>> is a concrete class in c++ according to the declaration of >>>> "%feature("interface")" in interface file. >>>> II)If a deprived class has two or more base classes, at least a base >>>> class will be implements as a interface according to the >>>> declaration of >>>> "%feature("interface")" ,others will be interfaces and concrete >>>> classes. >>>> III)If the base class is a concrete class, the corresponding >>>> interfaces >>>> are named with a prefix like "SWIGTYPE_interface_" >>>> IV)If the classes are abstract classes with definition of method in >>>> them, they will be the same as the concrete classes, or they will be >>>> just implemented as an interface of java . >>>> 2. the rule about which is interface and which is concrete class in >>>> java? >>>> Depending the order of base classes. >>>> If there is an abstract class in base classes, it has the highest >>>> priority, >>>> If there are two more abstract classes as base classes, depending the >>>> order of base classes. >>>> For example: >>>> CBase1,CBase2,ABase1 are all base classes, they can be implemented as >>>> interfaces through >>>> %feature("interface") CBase1,CBase2,ABase1 >>>> For Derived1, the java codes may like this : >>>> public Derived1 extends CBase1 implements SWIGTYPE_interface_CBase2{ >>>> >>>> . . . >>>> } >>>> because CBase1 is before CBase2,so a interface >>>> "SWIGTYPE_interface_CBase2" is needed,the java codes may like this >>>> interface SWIGTYPE_interface_CBase2{ >>>> int foo2(); >>>> } >>>> also there still is a concrete java class of CBase2 likes: >>>> public class CBase2 { >>>> . . . >>>> } >>>> >>>> For Derived2, the java codes may like this: >>>> public Derived2 extends CBase1 implements ABase1{ >>>> . . . >>>> } >>>> interface ABase1 { >>>> int bar1(); >>>> } >>>> ABase1 is an abstract class in c++ , it doesn't need to add new >>>> interface in java, it is direct map. >>>> >>>> >>>> I have read some source code of swig, and made a java test case in >>>> testsuite under William's help . >>>> Any suggestions will be appreciated,thanks all in advance. >>> >>> Hi Jiang >>> >>> I'm just considering your test cases. I'm not clear on some things... >>> >>> You mention that there are some rules for what an interface will >>> look like and the priority of class being the base class or an >>> interface. Is this something that a user must know and decide before >>> specifying %feature("interface") or is this something that SWIG will >>> detect? I'd always assumed that a user will specify what is going to >>> be an interface, with maybe SWIG doing some checking that it is a >>> "pure abstract base class". So there is no need for some rules... if >>> a class has multiple base classes the 2nd and subsequent classes get >>> ignored (like they currently do). Unless some of the classes are >>> specified as %feature("interface") in which case the first class in >>> the list that does not have %feature("interface") becomes the base >>> class. >>> >> My original idea is that SWIG will decide which is interface and >> which is base class according the order of c++ source code,As you >> said it is better specify by a user. >>> So using your examples above, if you have: >>> >>> %feature("interface") ABase1; >>> >>> and then for c++: >>> struct Derived2:CBase1,ABase1 {...}; >>> you'd have in java: >>> public class Derived2 extends CBase1 implements ABase1 {...} >>> >>> and for this c++: >>> struct Derived3:CBase1,CBase2,ABase1 {...}; >>> the java code would be: >>> public class Derived3 extends CBase1 implements ABase1 {...} >>> and swig would warn about CBase2 being ignored. >>> >>> I'm not sure I like III) where you introduce some SWIGTYPE_interface >>> types. I don't see how it adds any value other than adding >>> complexity. Let's do one thing at a time and map pure abstract base >>> classes into Java interfaces first. Secondly, lets also deal with >>> non pure abstract base classes with a rule that if one is marked >>> with %feature("interface") all the non virtual methods are ignored >>> so that an interface can be generated out of it. For example your >>> CBase2 will turn into: >>> >>> interface CBase2 { >>> int foo2(); >>> } >>> >>> and if you had something like: >>> >>> %feature("interface") Concrete; >>> struct Concrete { >>> int a; >>> virtual void virtualMethod {...} >>> void nonVirtualMethod() {...} >>> }; >>> >>> it would map to: >>> >>> interface Concrete { >>> void virtualMethod; >>> } >>> >>> ie the non virtual members would be ignored. Not a perfect solution >>> for multiple inheritance, but better than ignoring the whole class >>> as is currently done in multiple inheritance. >>> >> When use " %feature("interface") Concrete; " to map a concrete class >> into a java interface,if just generate a interface like this, >> interface Concrete { >> void virtualMethod; >> } >> a user may not instantiate a concrete class directly like this: >> Concrete c=new Concrete(); >> c.nonVirtualMethod(); >> And the "SWIGTYPE_interface" may be a redundant type the user doesn't >> map a concrete class into a java interface, but may be useful in >> aboved example. > Yes that is a problem and is one of the reasons why > %feature("interface") should not be turned on automatically. Another > reason is marshalling of this type between the two layers. So far we > have talked about returning the type from a function and the problems > it gives. But also consider when it is used as a parameter wrapping > this c++: > > void xyz(ABase1 *); > > As ABase1 is wrapped as a Java interface, it does not have any > swigCPtr member variables to store the underlying C++ pointer. It > needs to be stored somewhere else and retrieved from there too. > Suggestions? Perhaps when using these interfaces, we'd have to ignore > these methods as a simple but limited solution? > If the all abstract classes and concrete classes with declaration of "feature(interface)" are implemented as class and interfaces,for example: //cpp void xyz(ABase1 *); //SWIGTYPE_interface_ABase1 interface SWIGTYPE_interface_ABase1 { . . . } // ABase1 public class ABase1 implements SWIGTYPE_interface_ABase1 { . . . } //java void xyz(ABase1 ); Now the interface is just auxiliary.Is that feasible in SWIG?? >>> There is a patch knocking about which detects pure abstract base >>> classes and marks them as such (if I recall right). Have you looked >>> at this patch yet? This could be used to help detect classes that >>> can successfully be used as Java interfaces and warn if it is going >>> to fail. >>> >>> William >>> >> Is it in test-suite? > > Nope, see Ben Allan's emails and patch: > http://thread.gmane.org/gmane.comp.programming.swig.devel/17165/focus=17235 > > http://thread.gmane.org/gmane.comp.programming.swig.devel/17165/focus=17212 > > > William > Thanks !And could you tell me difference between the url you give me and the swig-devel mail list? They look like the twins! Best Regards Jiang |