Slashdot Mirror


Portable Coding and Cross-Platform Libraries?

Bradee-oh! queries: "My brother and I were just commissioned to develop a large energy management system for a few big college campuses in the area. It will be written in C/C++. We know that in 6 months, when a preliminary test system will be installed, it will be running on NT/2000 servers. The software will be tested on NT for up to 12 months and a final version will run on NT a year after that. We also know that around that time, it will shift to *nix servers, and we're expected to account for that in development. The question is, what sorts of cross platform libraries will make this as painless as possible? I've never made it a point to code for 2 platforms at once in any language other that Java. Aside from the GUI, which we've already agreed to use QT 3.0 for, we specifically are looking for cross-platform libraries for multi-threading, serial port I/O, and network I/O."

"Ideal libraries would be open source and free, though those aren't as important as tested/stable/reliable. What are your recommendations? Anyone have experience writing for multiple platforms at once with threading, serial I/O, and network I/O all in mind? The ideal scenario would be to recompile on the new platform without changing a line of code - will this type of portability be possible?"

31 of 531 comments (clear)

  1. A little known library is SFL by Hougaard · · Score: 3, Informative

    From www.imatix.com (The makers of the Xitami webserver).

    SFL is a great library for doing portable low-level stuff such as network etc..

  2. ACE ADAPTIVE Communication Environment by n-tone · · Score: 4, Informative

    ACE is an open-source framework that provides many components and patterns for developing high-performance, distributed real-time and embedded systems. ACE provides powerful, yet efficient abstractions for sockets, demultiplexing loops, threads, synchronization primitives.
    I've never tested this framework but it seems very good. I know several companies which use it and which are happy with it.

    1. Re:ACE ADAPTIVE Communication Environment by irix · · Score: 4, Informative

      I (and my company) also use this library extensively in a number of C++ projects to do multithreading, socket communications and memory maps, just to name a few things.

      It is open source, so it has the advantage that you can fix or patch bugs easily, and extend it if you want to.

      Even if you don't use the cross-platform part of ACE a lot, the C++ abstractions for some common UNIX paradigms are great to have - for example you can turn a class into a thread, etc.

      --

      Do you even know anything about perl? -- AC Replying to Tom Christiansen post.
  3. Question by SimonK · · Score: 5, Insightful

    Do you have a compelling reason not to use Java in this case ? It would seem to provide everything you require.

    Even just writing portable C++ code can be tricky, especially if one of the target platforms is Microsoft.

  4. Err, you told us didn't you? by mainframe_uk · · Score: 5, Insightful

    QT covers the multi-threading and network stuff so you're down to just serial port stuff aren't you. If you use QT properly then you should be fairly ok.

    1. Re:Err, you told us didn't you? by larien · · Score: 3, Informative
      Even if the serial stuff was written years ago, is that such a problem? What difference is there between a serial port 10 years ago and a serial port now? My guess is not a lot, other than perhaps faster baud rates, but I don't think even that has changed in about 5 years (how long have we had UART 16550?).

      Worst case scenario, put all the serial code into one file and use functions like open_serial_socket(), read_serial_data which call the underlying OS functions. When you move to Unix, swap out the file for the new version.

  5. Usr Open source tools by Lumpy · · Score: 4, Informative

    Your choice of Qt is a good start, but be sure to use GCC, all open source libs that exist on both sides, and adhere as closely to the ANSI standard as you can. If you do the footwork now and gather the libs and other files needed now for both sides AND keep cross compiling on both platforms as you go.

    Dont think you can make it under NT and then 2 years later that it will compile on *Nix magically, you need to test every step of the way.

    Oh and be sure you have the libs that are identical for both platforms and freeze them before you start. nothing kills a cross platform project faster then changing libs and finding later that the libs you built for on platform X are no-longer compatable with platformY's libs.

    --
    Do not look at laser with remaining good eye.
  6. wxWindows by Anonymous Coward · · Score: 3, Informative

    wxWindows (http://www.wxWindows.org) supports quite a few platforms, is open-source, has been developing since 1992, and might be probably exactly what you're looking for.

    1. Re:wxWindows by joerg · · Score: 4, Informative

      wxWindows has Networking support (socket I/O, ipc,... whatever you want), thread support, a rich feature set for GUIs and much more (unfortunately there is no support for Serial I/O).

      You might even consider to drop QT in favor of wxWindows.

      It is availabe for Windows, XWindows (GTK based), Mac and some other platforms. It is released under the LGPL.

    2. Re:wxWindows by erlando · · Score: 3, Informative

      And it has the IMO great advantage over Qt in that it uses native widgets where possible. Qt draws its own widgets afaik.

      Also the Qt-license is very restrictive. wxWindows has a license explicitly allowing the library to be used for commercial purposes.

      wxWindows runs on Windows, MacOS (9 and X), GTK(+). Work is underway to implement a universal version of the library to be run on embedded platforms.

      wxWindows is open-source. Patches and contributions are highly encouraged. Also the mailing-lists are very active with several of the main developers taking part in the discussion.

      --
      Remember, there are no stupid questions. But there are a lot of inquisitive idiots.
    3. Re:wxWindows by rs_nuke · · Score: 3, Insightful

      A year back when trying to find out if I should choose QT or wxWindows, I noticed very poor reliablity with QT, I did experience several cores just by compiling the samples that came with QT on all *nix plateforms. (Solaris,HP-UX,IRIX,DUX) I remember my Solaris box often cored after playing with QT widgets... However, QT was _rock_solid_ on Linux, and windows.

      wxWindows is far more a complete set GUI and more including I/O, networking, ODBC (database)! The nices part about wxWindows is the native look, of other *nix apps, on the unix world, which come with Motif R1.2 or better, using the Motif build of wxWindows gives a nice native look, and smaller executables! By linking with already found Motif libraries DSOs! I recalled some sample QT examples were like several megabytes! On non-x86 *nix boxes.

      For someone that has been working with wxWindows, and tried QT, by far, I think wxWindows wins hands down. I don't know why it isn't as "famous" as QT.

      My .02cents...

  7. At least use the STL.. by reachinmark · · Score: 3, Informative
    We have our own API that we used to support on both unix and NT. It was originally developed on IRIX, and we made extensive use of the C++ Standard Template Library which made things a bit easier when porting to NT.

    I realise that the STL isn't on the same level of cross-platform libraries that you were referring to, but it does aleviate some problems - and it's damn efficient too. Stream's, the way the STL uses them, can be quite an effective way of abstracting I/O.

    The biggest two problems we had was threading, and serial I/O. Threading, thanks to NT's posix libraries, wasn't that much of a pain - but we did need to write our own thread interface classes, one NT specific and one unix specific. Serial I/O was a little more tricky, but both came down to the same basic approach of treating the serial ports as files.

    I think the conclusion we came to was that it was a good idea to highlight the major differences first, and create your own wrapper classes around the OS specific methods. This way your main program is platform independant, and porting is kept to the wrapper classes.

    And of course, if you use the Cygwin environment, you shouldn't have any problems at all porting to another GCC platform.

    Only one warning: watch out for tricky C++ template uses, not all compilers support all features (e.g. Visual C++ lacks partial template specialisation amongst other useful features).

  8. NSPR by machingo · · Score: 5, Informative

    Check Netscape Portable Runtime, (just one of the many projects that are part of Mozilla. This library provide cross-platform threading, IPC, network/file IO, and dynamic linking, among other things.

  9. Rogue Wave by sql*kitten · · Score: 4, Informative

    You need SourcePro from Rogue Wave, formerly Threads.h++ etc. It provides a high level, easy to use C++ API for cross platform application development. Even if you're not going cross platform, the Rogue Wave stuff is excellent, provides loads of useful classes for threading, database access, network protocol handling and more.

    1. Re:Rogue Wave by Teancom · · Score: 3, Informative

      We have used .h++ for years around here for our main inhouse app. We decided just yesterday to remove all remaining dependencies and go to straight stl. Why? Because .h++ is not source-code compatabile with SourcePro, they provide no migration path, or even a "porting howto" (all according to our account rep). So we are faced with either spending the time and energy porting from .h++ to SourcePro, or spending the exact same amount of time and energy porting to the stl, with the side benefit of making our app linux compatable.

      Which reminds me, their linux port *SUCKS*. The latest and greatest .h++ will run on Redhat6.2, with gcc 2.95.2, the stock kernel, and *thats* *it* (not even perfectly, there are serious bugs). Any other platform (we've tried mandrake 7.2,8.0,8.1;debian2.1,2.2;redhat 7.0,7.2) will segfault/core dump. Their next release, due January, will run on redhat 7.1. I have no doubt that it will fail to run on anything else. So it really falls down wrt cross-platform compatability.

      So, to summarize, if you happen to be running one of the "tier-one" plarforms, their libs are pretty decent. Anything else, even if it's listed as "compatable", and you'll be screwed.

      (as a quick example of what I'm talking about, our app has different defaults depending on what it was called as, tc vs. frpt vs. etc, and it does a simple check of ARGV[0] to see if it .contains the various names. It doesn't work on linux. Flat-out returns the wrong value. And that's on redhat6.2. Any attempt to use their string class will immediately seg-fault. I'm seriously disappointed, in case you couldn't tell.)

  10. This is wrong by Nicolas+MONNET · · Score: 3, Offtopic

    Writing cross platform GUI applications is hard. Writing cross platform GUI applications with multithreading and network stuff is very hard, but most of all hard to get right.

    Hard = difficult = long = costly.

    The question is, is the cost worth it? This application, from what you're telling us, is going to run on a few dozen computers at most. It's not a general purpose app, there is no added value in providing cross platform support.

    Why switch platforms in the end? It doesn't make any sense.

    But to answer your question, if Windows is really a transitional system, I would just develop on *nix, and run it on Windows with Cygwin. Might be even simpler to use XFree/Cygwin.

  11. Can it be browser based? by Ami+Ganguli · · Score: 5, Insightful

    I'm not sure what you mean by "Energy Management System", but if the interface isn't heavily interactive, I'd go with a browser front-end. If you can, use Mozilla and XUL. It allows you to build really nice interfaces easily.

    Browser-based apps aren't going to replace everything. Highly interactive things like word-processors, spreadsheets, etc. aren't suitable for browsers, but if the interface is form-based I think it's the way to go.

    The obvious advantage in your case is that the interface code is painlessly cross-platform. You still have to worry about lower level stuff, but that's much easier to do properly if you eliminate the GUI.

    --
    It is tempting, if the only tool you have is a hammer, to treat everything as if it were a nail. - Abraham Maslow
  12. A more comprehensive approach by Anonymous+Brave+Guy · · Score: 5, Insightful

    While cross-platform libraries will help, some things just work differently on different platforms, and you're unlikely to find a library covering everything so that all it takes is a rebuild to port.

    As an alternative strategy, and one that's often easier in practice, I suggest you adopt the old programming rule of thumb: isolate anything platform specific in your code. If you're developing using C++, for example, define interfaces (probably via abstract base classes or in terms of templates) that represent the low-level functionality for serial comms, threading or whatever. Write all your higher level code in terms of those interfaces.

    Then you just need to write the implementation behind them for each platform. This may be as simple as writing a few inline forwarding functions if your platform provides native APIs to do what you want. (Obviously I'm including any platform-specific or cross-platform libraries you have in the term "APIs", not just OS-provided functionality.) If, for any particular platform or library, there isn't a direct API to do what your interface requires, you can write a more complex routine in your implementation using the APIs that are available. It will still be isolated from the rest of your code, and nothing higher-level should need changing (or, hopefully, even rebuilding).

    If you adopt this approach, the vast majority of your code will probably be 100% portable, because all it depends on is your own "middle level" APIs. Those can be implemented in whatever way is most convenient on a given platform, which might still include writing them in terms of a cross-platform library. The key thing is that most of your code isn't tied to anything platform-specific at all this way, and as such is immediately portable anywhere as long as your middle-level interfaces are sensible -- which they will be, of course, since you wrote them. ;-)

    --
    If you disagree, post your argument. (-1, Overrated) isn't your personal censorship tool for views you don't like.
    1. Re:A more comprehensive approach by interiot · · Score: 3, Insightful

      So, write your own cross-platform library since none available is taylored to your own needs. ?

  13. And why can't you use Java? by Anonymous Coward · · Score: 5, Informative
    You clearly point out that you have prior experience with Java. Java meets all of the requirements you listed:
    • Cross Platform
    • Portability without changing a line of code (or recompiling for that matter)
    • Multi-threading
    • Serial I/O
    • Network I/O

    In addition, you can get security, high availabilty, and scaleability with far less effort and platform-dependence than a C/C++ solution.

    Are you being forced to use C/C++ simply because of QT? Have you considered using QT in conjunction with Trolltech's QT AWT?

    1. Re:And why can't you use Java? by OblongPlatypus · · Score: 3

      Isn't multithreading still fairly shoddy in Perl 5? They say it'll be great in Perl 6, but at the rate things are going these days, Perl 6 is still a long way off.

      --
      -- If no truths are spoken then no lies can hide --
    2. Re:And why can't you use Java? by mvw · · Score: 4, Interesting
      Java meets all of the requirements you listed:
      • Cross Platform
      Which means it will run with all promised features only on Win32, with some drawbacks under Solaris, with other drawbacks under Linux (where it has a strange status between supported and unsupported) and is not supported at all under *BSD. The situation for Mac is not known to me, Jave seems to be available lately.
      • Portability without changing a line of code (or recompiling for that matter)
      Both is not true in general. Only non GUI programs, using only established APIs have a change to run without modification, so much for source compatibility. For byte code it turned out, that while the byte code it self might be stable, other stuff changed so much over time, that you are forced to recompile old classes (I had this experience with many security related APIs).
      • Multi-threading
      Multi-threading is still a complicated matter under Java, perhaps it is a bit easier because one just deals with one implementation per plattform in general.

      But implementation is still different. Under Win32 you get preemptive multitasking, under other implementations (like Solaris up to certain revision) you have only cooperative multitasking. So you are still forced to stray yield() or sleep() into your loops.

      I found debugging multithreaded apps under Java complicated as well, not too much help from the JBuilder IDE I used, and I was not able to detect certain stall conditions with JProbe's threadalizer. (Blame it on me or the tool :) I had to work things out with classic printf style debugging that gave me a hint, what thread was doing what.

      • Network I/O

      Berkley sockets are quite standard, be it UNIX or Win32 (WinSocks) that is not that hard.

      • In addition, you can get security, high availabilty, and scaleability with far less effort and platform-dependence than a C/C++ solution.
      I think that statement is bullshit. It largely depends on the experience of your programmer what is easier to use.

      In my experience Java is still unforgiving. Good code runs well, but you will feel it if you run sloppy or bad code, be it speed or memory wise. Under C/C++ there is a certain margin of tolerance in that area. Alas you have to grok pointers, which seems to be seen as a problem todays.

      On the good side Java has some large standardized libraries and nice development tools. I also believe that the average Java code is more modern, because it uses these modern libs.

      Both approaches C++/QT/NSPR whatever or Java might lead to a working solution. Each has its strongnesses and weaknesses. (And there is other stuff, like functional languages :)

      Again I would take the experience of the crew as the deciding factor.

      Regards,
      Marc

  14. Re:You have the answer by jawtheshark · · Score: 3, Informative

    Crippled? Hmmm, I don't know if that is true. Java in itself is an elegant language which has some limitations due to trying to support such a wide range of platforms transparently. You have to know what you are doing, that is all...but that counts for any language.
    Java code runs fast (really fast) in a lot of cases, mostly the only thing that "feels" slow is the GUI. You can really enhance responsiveness by including intelligent Threading. You can also avoid creating of throwaway objects, thus limiting Garbage collection.
    For the GUI, just don't use Swing if you don't need to... AWT is enough for simple frontends, yes it is not perfect, but it is faster. I suppose it is even possible to write your own native implementation linking to, for example, QT libraries or W32 libraries. Not portable, lot of work, but speed ensure.
    Some people tend to forget: using a vitual machine inherently takes some performance, but that is the price to pay for excellent multi-platform support. Note that it's still is better to do test on all the platforms you want to support, but the implementation is done once. Especially when using applications (not applets, because of browsers (non)support ), mult-platform Java applications tend to work astonishingly well in my experience.

    --
    Ahhh...the great dumpster continuum. Many a free computer will be found there. -- sowth (748135)
  15. From someone who has used ACE professionally by Christopher+Bibbs · · Score: 4, Insightful

    It is quirky, a pain in the rear, time consuming, but less so than other cross-platform libraries.

    I've used it in projects that required common threading, interprocess communication, and a few other things across NT, Solaris, HP-UX, AIX, and Linux. I point out all of the UNIX-like platforms as seperate entities because they all have enough quirks that you can't expect any given library to work across the board.

    Oh, and to everyone that has been promoting ideas like "just use gcc" or "just use straight c++", maybe you've never worked on a large scale, long term project, but gcc is not the best option for an app that needs to be highly optimized and writting everything in c++ from scratch is a waste of time (that's why we have libraries in the first place). I'm not flaming here, just pointing out that you need to look at the bigger picture.

    1. Re:From someone who has used ACE professionally by RalphTWaP · · Score: 5, Insightful

      Absolutely,

      As someone using ACE at the moment (well, in another screen). I can say that I've never found a more well-constructed cross-platform middleware package. You can find it here. In addition, the DOC group's TAO package provides a CORBA implementation on top of ACE that works really well for... well, those CORBA things *grins*.

      One drawback when using any middleware package that I've seen is that you have to buy in pretty heavily to the package, somewhat adopting the development philosophy of the package's designers. With ACE that hasn't been as much of a problem (For instance, it provides a method of dispatching QT events) mostly because the underlying design is heavily pattern based.

      On other fronts, I also continually find the Boost libraries to be very useful. They can be found here.

      Probably the last thing to consider is that if you vary your development platform, you are likely going to be changing your C/C++ implementation--and they are not all created equal. Personally, I've found that the cross-platform availability and easy integration of the Dinkumware C/C++ libraries are pretty much worth the middle-of-the-road costs involved. Dinkum's located here.

  16. Re:You have the answer by tbone1 · · Score: 3, Interesting
    Unless the specs are that it is to be written in C/C++.

    And this is all too common, I'm afraid. I once had to implement a massive, heavy-fines-for-errors project that needed to compare massive associative arrays in C instead of Perl. Why? Because the boss didn't like Perl.

    --

    The Independent: Reverend Spooner Arrested in Friar Tuck Incident - ISIHAC, Historical Headlines
  17. Re:You have the answer by statusbar · · Score: 3, Interesting

    Actually, no, but he DOES already have the answer.

    QT 3.0 supplies everything he needs for platform independent sockets, threads as well as the gui. Serial port access is easy enough on both platforms to do yourself.

    My only suggestion is to have a spare linux box with a cron job that checks out the latest sources from cvs, compiles, and emails you the error messages. Then he will be notified as soon as he checks in some sources that only compile on the lame VC++ compiler. I do that all the time and it is much easier to fix the portability problems as you go instead of in one big chunk at the end.

    --jeff

    --
    ipv6 is my vpn
  18. portable CORBA and threading: omniORB by matthew_gream · · Score: 3, Informative

    For portable CORBA and threading support, try omniORB (http://www.uk.research.att.com/omniORB/omniORB.ht ml). We use it for seamless portability between NT4.0 & Solaris components and its very effective.

    --
    -- Matthew - matthew.gream@pobox.com, http://matthewgream.net
  19. Java, baby by twdorris · · Score: 5, Informative

    Seriously. Most folks on here think Java sucks, but that's typically because they haven't actually *used* it. I think perl sucks, simply because I haven't used it and don't know it well enough to be efficient at it. That's all too common. But take a closer look at Java... It's cross platform, multithreaded, scaleable ('cept that pesky GC thing, which can be handled reasonably enough with intelligent coding), and does all the stuff you're looking to do.

    I used to code exclusively in assembly, then C, then C++, and now Java. Trust me, Java is a stable alternative that will solve MANY of these cross platform issues for you, if not all.

    As an example, I have written a datalogger for my car. I coded everything under Linux using vi. It's a Swing based app that's multithreaded and uses the serial port to communicate with the car's computer. I never gave a second thought to cross platform support. I just coded to the Java APIs.

    One day, a friend of mine wanted to run the thing on his laptop...which had Windows 98 on it. Sure enough, I put the files onto his laptop and it ran perfectly. This was not modified in any way and didn't even get recompiled! I just put the jar files from my Linux box onto this Windows laptop and away it went. I told him this "should" work, and sure enough, it did.

    As for scaleability, I have also helped design a VERY large scale middleware Java RMI server architecture for a VERY large shipping company (it's a public company...you know them...I'm positive you've used them). This handles all user-based load from their VERY large website. We're talking millions of transactions a day here, not thousands. With proper attention to garbage collection, multithreading, and a distributed architecture, this system runs without flaw, 24/7.

    So Java works in real world examples, it really does. Plus, it promotes code reuse so well, that I can't imagine suggesting any other solution for your problem.

  20. Depends... by Svartalf · · Score: 3, Informative

    If they're doing a lot of I/O device control directly with the app (Uh, this is an energy management system- which, by definition is going to be tickling things like Opto-22 panels, reading from sensors, etc...) then Java's only truely useful as a UI choice as they're going to have to come up with native interface code to drive the Opto-22 stuff.

    They not only have to do network programming and serial comms, they have to deal with industrial I/O that may/may not have a serial interface. If it does all have serial interfaces, they're going to have to come up with APIs for those devices- which isn't always easy.

    Java meets only part of the criteria- the ones they needed help with answers on. It doesn't magically meet the other criteria- what are they working with and what does the customer want. I suspect that Java doesn't make the grade here for some reason. I code in Java as well as C, C++, and Forth. I'd be using Forth or C/C++ for this sort of thing with maybe a CORBA driven UI coded in Java unless the customer requirements insisted on C/C++ for everything. Then I'd be using C/C++ because it's close enough to cross-platform to matter little if you pay close attention to your code. I know, I've been doing this sort of thing professionally for 7 years now.

    --
    I am not merely a "consumer" or a "taxpayer". I am a Citizen of the State of Texas
  21. Yup, only way to code for the future. by Medievalist · · Score: 4, Insightful

    ABG is right, and you should isolate core functionality from data access and user interface - this is critical to portability and leads to evolution of strong, mature systems.
    You will note that many business systems written in COBOL as "code monoliths" now require extremely expensive support in the form of CICS compatibility and cumbersome, user-unfriendly security layers. And their interfaces are still "green-screen" or, in many cases, have actually lost function and ease of use through poor GUI integration.
    Meanwhile, many scientific systems written in a modular fashion live on despite having their underlying hardware replaced and their user interfaces re-written repeatedly. I'm sure there are systems that started on PDP-11s, are now running on Alpha VAXen, and are planning ports to linux clusters. Some will have been fitted with very pretty web interfaces.
    Write your core modules, where the work is done, in ANSI C. Write your data access routines in the most portable language available on your preferred platform, and keep the code entirely distinct from the core functionality and user interface. If you're already invested in something like Rdb, Oracle, MySQL, whatever, then leverage the expertise and investment you already have but make sure your API is callable from C. Don't be afraid to use a fast, simple data store like Berkeley DB or plain old flat files - cheaper is better. But be sure to define a data access API in any case (such as Replace_Leaf_Record() and Create_New_Root(), for example) and keep the code cleanly separated into modules.
    Provide a "raw text" interface, written in C, and keep that as the base functionality canon. Use it to test the GUI, which you can write in Java or C++ or Eiffel or whatever (I'd say use your favorite, since you'll get prettier results if you enjoy using the language). Make sure the API for the GUI is entirely documented in the core code itself so that it can be seamlessly replaced when the fabled post-GUI interface finally appears.
    --Charlie