cross-platform c++ classes?

Lucas Vogel plug-devel@lists.PLUG.phoenix.az.us
Mon May 21 13:45:02 2001


Hi Rob!

> -----Original Message-----
> From: Rob Wehrli [mailto:rwehrli@azpower.com]
> Sent: Tuesday, May 22, 2001 3:06 PM
> To: plug-devel@lists.PLUG.phoenix.az.us
> Subject: Re: cross-platform c++ classes?
> 

> I can't think of any good reasons for what it *appears* that you're
> proposing, but I haven't seen GSD, either.  It sounds a lot more like
> you need to rewrite the documentation or maybe just re-read 
> it.  If, in
> fact, there is a substantially different public interface used for a
> Win32 version of the library and the X Window version of it, 
> then to use
> the words cross-platform or platform-neutral in conjunction with it is
> inappropriate.  
>I've seen far worse, but there is no reason to try to
> "fix" them IMHO.  A complete rewrite and delta divergence is 
> required. 
> Deprecate the old ways of thinking and start implementing the new ways
> through any of many strategies.  Writing platform specific 
> code with C++
> "classes" is nearly criminal.  The C++ "core" should 
> definitely use some
> service provider interface to platform specific implementations that
> abstract to a higher-level, common API.  If you can't do it cleanly,
> then consider rewriting it.  Anything else becomes a nightmare to
> maintain and describe while also building into it many variations of
> documentation and related support.
> 
> Maybe I missed it, is GSD C or C++?

The GSD library is, in essence, a single object(as in .dll or .a) library
(written in C) with a list of a couple hundred function calls(API's?) that
you use to do different things with. The documentation(which is very poor
indeed) splits all of these APIs into the following libraries:

	Draw
	Plot
	Message
	Utility
	Attribute
	Attribute Conversion
	Database
	Data View
	Field Data
	Hierarchy
	X Window Symbol Palette
	X Window Frequently Used Symbol Palette
	SputSget BE
	SputSget LE
	X Window Draw
	X Window Utility
	NT Draw
	NT Utility
	Schema
	Menu
	X Window Attribute MMI
	X Window FreeHand Toolbar
	DMA Conversion
	Geo
	Parse
	Overlay
	X Window Database MMI
	X PixMap
	Validate

What I want to do is create a set of C++ classes that will wrap around these
api calls so that I have actual objects to handle the data. I initially was
just going to do a platform-specific (COM, windows) set, but it appears that
with the exception of the libraries that start with "X Window" or "NT" I
could quite a bit done that might a. be useful to someone else and b. be
portable to other supported platforms. It may even be possible to make a
some classes with the platform-specific sets that could be generic enough
that if, say, I wanted to make a "NT Window Database MMI" class I would be
able to inherit from a generic class. 


> > and rendering custom graphics, etc. - the documentation for 
> GSD speaks in
> > two ways, one in terms of X and another in terms of 
> Windows. By having a
> > platform-specific subset I would be able to implement those
> > platform-specific aspects separately.
> 
> The idea of a "subset" of classes is very weird indeed.  
> Class libraries
> tend to be hierarchical.  A *set* of classes that use interfaces of
> another set of classes is not a subset of the other set, but a
> relationship definitely exists.  A true "subset" of classes would tend
> to fall under the branches of a derived base class somewhere up the
> inheritance ladder...but then, we don't really talk about them as
> "subsets," rather, derived classes.  Considering a library to be a set
> of classes and describing some portion of them to be a subset of the
> library is probably ill-fated, at best.  The relationships that exist
> between classes in a single library are not well-defined 
> using sets and
> subsets.  If you were to take a few libs out of your /usr/lib 
> directory
> and say, here is a subset of libraries, well, from the perspective of
> some of a greater number of files in a path, it makes some 
> sense because
> there isn't necessarily any relationship between the PATH and 
> the subset
> to distort the truth.  However, in a *class hierarchy* (even when
> considering multiple inheritance, which certainly throws a decently
> large wrench into the discussion), which is likely *packaged* in a
> library, the relationships between the individual classes is typically
> well-defined as poorly defined relationships result in crappy class
> hierarchies.
> 
> My goal here is not to pick apart the words you've chosen for this
> discussion, but to ensure that we're communicating along the same
> lines.  If what you implement creates a problem with the "natural"
> hierarchy within a class library, you are causing yourself grief by
> considering it.  If, on the other hand, your new code supplements and
> blends well with the natural order in the library, then 
> you're adding to
> its grace and beauty.  

You're right, my choice of words was pretty bad. 

In a nutshell, the purpose of this library is to create a base set of c++
classes that manipulate this GSD library to make it easier to understand and
use. The library will hide the API calls to the GSD library and allow me to
inherit from a set of classes into more specific applications, such as the
COM wrappers for Windows, while still giving me a library to use should I
try to use the library for something on Linux. To use your words, I want to
add to its grace and beauty.

>What few people realize about C++ is that it is
> not good enough to be a purely good mechanical implementor of the
> language.  Good C++ is a combination of good mechanical implementation
> and true art (as opposed to "fine" art, which is expensive and sits
> around collecting dust for people who have enough time to appreciate
> it).  OOP newcomers tend to be neither good mechanics nor 
> good artisans,
> and all-too-frequently, they lack the fundamental 
> "wherewithall" that is
> the OOP mentality needed to be a halfway decent implementor.  
> While I'm
> not suggesting that you don't have it or that you can't learn it, your
> choice of words doesn't seem to imply it.  Perhaps the 
> possibly greatest
> failing a programmer can do is to misuse a language to accomplish some
> goal.  Hey, it works, right?  The key to good programming is
> understanding.  If the code is easy to understand and the 
> implementation
> matches some basic set of known patterns (GOF) or methods of
> accomplishing results in a way that other programmers intuitively
> comprehend, then the code is at least "useful."  How well it does the
> desired job can then be improved upon with a better mechanical
> implementation of the properly abstracted algorithms used to 
> perform the
> actual work.  That, not-so succinctly, is the goal of any class
> "library" builder.  If you at least do that, you can't make too many
> foolish mistakes and "corrupt" the intention of the language without
> being a rather obvious "bull in the ole china shop."  

I am trying to take a library that is required for use and hard to
understand and place a well-written, neatly-organized, well-documented,
comprehensive set of classes on top of it. From that I want to create a set
of well-written, neatly-organized, well-documented, comprehensive COM
objects that inherit from those classes and create a very powerful and
easy-to-use library for handling the GSD functionality. 

>C++ will let you
> compile just about anything that doesn't have two mains in compilation
> unit.  I spent probably 4 hours once trying to trick it into 
> letting me
> overload/override/redefine/bastardize main just to see if I 
> could do it,
> but true to the standard, gcc wouldn't let me!  I stopped 
> just short of
> defining an operator to take the place of main :)
> 
> 
> ...if you haven't tried this one, please do...
> 
> #include
> <stdio.h>                                                            
> main(t,_,a)                                                   
>                 
> char
> *a;                                                           
>            
> {                                                             
>                 
> return!0<t?t<3?main(-79,-13,a+main(-87,1-_,main(-86,0,a+1)+a))
> :               
> 1,t<_?main(t+1,_,a):3,main(-94,-27+t,a)&&t==2?_<13?           
>                 
> main(2,_+1,"%s %d
> %d\n"):9:16:t<0?t<-72?main(_,t,                             
> "@n'+,#'/*{}w+/w#cdnr/+,{}r/*de}+,/*{*+,/w{%+,/w#q#n+,/#{l+,/n
> {n+,/+#n+,/#\   
> ;#q#n+,/+k#;*+,/'r :'d*'3,}{w+K w'K:'+}e#';dq#'l
> \                            
> q#'+d'K#!/+k#;q#'r}eKK#}w'r}eKK{nl]'/#;#q#n'){)#}w'){){nl]'/+#n';d}rw'
> i;# \  
> ){nl]!/n{n#'; r{#w'r nc{nl]'/#{l,+'K {rw' iK{;[{nl]'/w#q#n'wk nw'
> \           
> iwk{KK{nl]!/w{%'l##w#' i; :{nl]'/*{q#'ld;r'}{nlwb!/*de}'c
> \                   
> ;;{nl'-{}rw]'/+,}##'*}#nc,',#nw]'/+kd'+e}+;#'rdq#w! nr'/ ') 
> }+}{rl#'{n'
> ')# \ 
> }'+}##(!!/")                                                  
>                 
>  
> :t<-50?_==*a?putchar(31[a]):main(-65,_,a+1):main((*a=='/')+t,_
> ,a+1)         
>    
> :0<t?main(2,2,"%s"):*a=='/'||main(0,main(-61,*a,              
>             
> "!ek;dc i@bK'(q)-[w]*%n+r3#l,{}:\nuwloca-O;m
> .vpbks,fxntdCeghiry"),a+1);      
> }
> 
> ..besure to leave strict ANSI off and use gcc.  It is beautiful, but I
> can't take credit for
> it.                                                           
>                   
> 
> 
> > 
> > > > that way I still have a platform-neutral codebase that anyone
> > > > could use in general, with a specific implementation that I
> > > need for what
> 
> How could anyone "use" the platform-neutral form if it requires a
> specific implementation for some other user type?  You'd be better off
> writing a COM wrapper to the existing base or finding an appropriate
> common interface and tying it into your COM object.
> 
> > > > I'm doing-which, in this case, would be a windows/COM
> > > > implementation of the
> > > > core.
> > >
> > 
> > Lucas
> 
> HTH...

It does. 


Lucas