johnson@cs.purdue.EDU (Bret Johnson) (06/04/90)
I am considering buying Turbo C++, but I need to link to a library that is compiled with Microsoft C. Specifically, I need to link to the C interface library packaged with the KnowledgeMan database system. (This library is called TBL; it used to be called KC.) As I understand, Turbo C, and thus I assume Turbo C++, sometimes works with libraries compiled with Microsoft C and sometimes does't. Could anyone please report their experiences using Turbo C with libraries compiled with Microsoft C. Are there any rules as to when things work and when they don't? Thank you. Bret Johnson johnson@cs.purdue.edu
tjr@cbnewsc.att.com (thomas.j.roberts) (06/05/90)
There are several (many ?) differences between Turbo C and Microsoft C. Some of them are harmless, some will kill your program; some will kill MS-DOS, some might even trash your disk(s). THIS IS PROBABLY NOT A COMPLETE LIST! 1) TC returns 4-byte results in AX/DX; MC uses AX/BX (float/double are returned in 8087 Top-Of-Stack register). This will make any large-pointer function misbehave dangerously, and will give erroneous results from any long function. 2) TC and MC use different names for the various segments. This will probably prevent it from linking properly (except for huge model programs), and will cause subtle errors in a huge-model program. 3) TC and MC package library routines differently, so you cannot use both the MC and the TC run-time libraries. If the third-party library depends upon the MC run-time library, this may cause link and/or run-time problems. 4) TC and MC have different requirements for subroutines to preserve register contents. This will cause a serious disaster during execution (write-protect those disks before executing!). 5) The TC run-time library screws around with the console hardware (even if you don't call any of its TEXT or GRAPHICS routines); this can often be minimized by setting directvideo=0. In most cases, even if you manage to get the linker to link the program and libraries without error, it will still die a horrible death when executed (usually taking MS-DOS down, too). In short, I strongly advise against trying to mix compilers in the same program. If you simply cannot afford to buy the other compiler, then you probably can make it work with the following kludges: 1) use TC huge model, and MC large model. 2) wrap every MC library routine with a special assembly routine to satisfy BOTH TC and MC register conventions (MC routine calling MC routine is probably OK as is). This special routine will need to manage DS. Good luck [you will really need it!]. Tom Roberts att!ihlpl!tjrob
mcdonald@aries.scs.uiuc.edu (Doug McDonald) (06/05/90)
In article <1990Jun4.205834.13661@cbnewsc.att.com> tjr@cbnewsc.att.com (thomas.j.roberts) writes: >There are several (many ?) differences between Turbo C and Microsoft C. > >1) TC returns 4-byte results in AX/DX; This I have no idea about. > MC uses AX/BX WRONG!!! Microscoft C uses AX/DX Doug McDonald
dhinds@portia.Stanford.EDU (David Hinds) (06/06/90)
In article <1990Jun4.205834.13661@cbnewsc.att.com> tjr@cbnewsc.att.com (thomas.j.roberts) writes: >There are several (many ?) differences between Turbo C and Microsoft C. >Some of them are harmless, some will kill your program; some will kill >MS-DOS, some might even trash your disk(s). > >2) TC and MC use different names for the various segments. >3) TC and MC package library routines differently. >4) TC and MC have different requirements for subroutines to preserve > register contents. >5) The TC run-time library screws around with the console hardware > >In short, I strongly advise against trying to mix compilers in the same >program. If you simply cannot afford to buy the other compiler, then >you probably can make it work with the following kludges... > This sounds like an appropriate place to mention some of the benefits of the Topspeed C compiler vs. Microsoft or Turbo C. The topspeed compiler allows you to specify just about anything having to do with calling conventions on the fly - segment names, parameter passing in registers, stack frame layout, inline function expansion, and register preservation. And you can recompile the run-time libraries to use whatever calling conventions you like. So, you can generally use most 3rd party libraries, regardless of what compiler they were generated with, if you know its calling conventions. You just add some compiler directives to the header files. -David Hinds dhinds@popserver.stanford.edu
bmarsh@cod.NOSC.MIL (William C. Marsh) (06/06/90)
Just thought I'd correct a few things, but mostly Tom's comments are correct: In article <1990Jun4.205834.13661@cbnewsc.att.com> tjr@cbnewsc.att.com (thomas.j.roberts) writes: >1) TC returns 4-byte results in AX/DX; MC uses AX/BX (float/double > are returned in 8087 Top-Of-Stack register). Wrong. Both use DX:AX for longs, far pointers, etc. I don't know about floats. >4) TC and MC have different requirements for subroutines to preserve > register contents. This will cause a serious disaster during Both have requirements to save BP, SI, and DI (and DS!). All others are fair game for both compilers. >5) The TC run-time library screws around with the console hardware > (even if you don't call any of its TEXT or GRAPHICS routines); > this can often be minimized by setting directvideo=0. Shouldn't matter to a third party routine, since Microsoft doesn't mess about with the hardware, and the library would have to deal with it anyway. >In most cases, even if you manage to get the linker to link the program >and libraries without error, it will still die a horrible death when >executed (usually taking MS-DOS down, too). Probably. It's probably the segments (and groups) that are going to kill you, also with internal functions (like long variable manipulation stuff) that would be called in the third party library which are not in the TC library. Bill -- Bill Marsh, Naval Ocean Systems Center, San Diego, CA {arpa,mil}net: bmarsh@cod.nosc.mil uucp: {ihnp4,akgua,decvax,dcdwest,ucbvax}!sdcsvax!nosc!bmarsh "If everything seems to be coming your way, you're probably in the wrong lane."
bright@Data-IO.COM (Walter Bright) (06/06/90)
In article <1990Jun5.134159.9577@ux1.cso.uiuc.edu> mcdonald@aries.scs.uiuc.edu (Doug McDonald) writes: <In article <1990Jun4.205834.13661@cbnewsc.att.com> tjr@cbnewsc.att.com (thomas.j.roberts) writes: <<There are several (many ?) differences between Turbo C and Microsoft C. <<1) TC returns 4-byte results in AX/DX; <This I have no idea about. << MC uses AX/BX <WRONG!!! Microscoft C uses AX/DX Zortech also uses AX/DX. In fact, Zortech follows exactly MSC's segment conventions, register saved/destroyed conventions, return value conventions (including struct returns), Pascal conventions, etc. The only difference is in floating point returns, ZTC's is different in order to make it reentrant. This is not enough, however, to make a 3rd party MSC library work with ZTC. Trouble areas are: 1. Using floating point. 2. Depending on 'compiler helper' functions in the rtl, like long divide. 3. Depending on the exact size and layout of the _iob[] struct in stdio.h (they're different between most compilers). This can cause very subtle crashes. 4. Using undocumented internal MSC library functions. 5. Depending on non-standard behavior of library functions (like strange things in printf format strings). This is not to say it's impossible. For example, ZTC programs can use the Microsoft Windows SDK libraries and the OS/2 PM libraries. This works because I made it work. It's just that you can't casually do this. Sometimes, people try and make things work by linking in *both* the MSC runtime libraries and the ZTC runtime libraries. This is nearly always doomed to failure, the usual result is lots of multiply-defined symbols from the linker. Even if it linked successfully, just imagine what would happen when you get some modules thinking _iob[] has one layout talking to other modules thinking something else... not a pretty thing to do to your hard disk! In other words, the most practical courses of action are: 1. Only buy libraries that come with source, and recompile it for the compiler you're using. 2. Call the library vendor and request a version for the compiler you're using.
david@csource.OZ.AU (david nugent) (06/06/90)
In article <1990Jun4.205834.13661@cbnewsc.att.com>, tjr@cbnewsc.att.com (thomas.j.roberts) writes: > 1) TC returns 4-byte results in AX/DX; MC uses AX/BX (float/double > are returned in 8087 Top-Of-Stack register). This will make any > large-pointer function misbehave dangerously, and will give > erroneous results from any long function. This is not the case. Both compilers return long/large pointers in DX:AX > 2) TC and MC use different names for the various segments. > This will probably prevent it from linking properly (except for > huge model programs), and will cause subtle errors in a > huge-model program. Since TC 1.5, Borland have been using identical segment naming conventions to Microsoft. Besides, they can be changed in TC to suit. > 3) TC and MC package library routines differently, so you cannot > use both the MC and the TC run-time libraries. If the third-party > library depends upon the MC run-time library, this may cause > link and/or run-time problems. By and large, they are similar. The problem really arises in the "help functions" used by the compiler for, say long division, multiplication and shifting. They are named and called differently and each library compiled with it's own compiler will of course use only it's version. > 4) TC and MC have different requirements for subroutines to preserve > register contents. This will cause a serious disaster during > execution (write-protect those disks before executing!). Not at all true. Both compilers require preservation of _only_ DS, SI, DI and BP. > 5) The TC run-time library screws around with the console hardware > (even if you don't call any of its TEXT or GRAPHICS routines); > this can often be minimized by setting directvideo=0. Which has little to do with the compatibility between compilers... david -- Unique Computing Pty Ltd, Melbourne, Aust. david@csource.oz.au 3:632/348@fidonet 28:4100/1@signet
bmarsh@cod.NOSC.MIL (William C. Marsh) (06/07/90)
In article <8@csource.OZ.AU> david@csource.OZ.AU (david nugent) writes: >Since TC 1.5, Borland have been using identical segment naming conventions >to Microsoft. Besides, they can be changed in TC to suit. However, if you change the names, you then have problems linking in the default library. Large model may get around this, but for smaller jobs it would be a big problem... Bill -- Bill Marsh, Naval Ocean Systems Center, San Diego, CA {arpa,mil}net: bmarsh@cod.nosc.mil uucp: {ihnp4,akgua,decvax,dcdwest,ucbvax}!sdcsvax!nosc!bmarsh "If everything seems to be coming your way, you're probably in the wrong lane."
joe@proto.COM (Joe Huffman) (06/08/90)
In article <2533@dataio.Data-IO.COM>, bright@Data-IO.COM (Walter Bright) writes: > In article <1990Jun5.134159.9577@ux1.cso.uiuc.edu> mcdonald@aries.scs.uiuc.edu (Doug McDonald) writes: > <In article <1990Jun4.205834.13661@cbnewsc.att.com> tjr@cbnewsc.att.com (thomas.j.roberts) writes: > <<There are several (many ?) differences between Turbo C and Microsoft C. . . . > In other words, the most practical courses of action are: > 1. Only buy libraries that come with source, and recompile it for the > compiler you're using. > 2. Call the library vendor and request a version for the compiler you're > using. One thing that I expected Walter to say but didn't, is that it is possible for library vendors to supply a single library that will work across MSC, TC, and Zortech C/C++. This is not possible in all cases, but in many it is. Walter had suggested I do this (and provided considerable help) with the graphics library that is shipped with Zortech C/C++ (we have since removed this feature, it now only works with Zortech). It is also possible to make this single library work with all memory models. The basics of the procedure for doing this is: 1) Use patchobj (from Zortech) on all .OBJ modules to remove references to the memory model the library was compiled under and default library searches. 2) Declare all functions and pointers as 'far'. Compile the library in "Large" memory model. 3) Provide all your own low level functions. Have NO unresolved externals from your library (use libunres supplied by Zortech to find them). This is a subtle problem, because the compiler generates function calls for things you didn't explicitly call, like long arithmetic. I achieved this by compiling my library with Zortech C and includeing the run time long arithemetic module (with the functions renamed) in my library. Use patchobj to rename all the long arithmetic functions to the new names. Hints, warnings, etc: In the FG graphics library I had to supply a few odds and ends functions like strcpy() and strcmp(), etc. These were either made static or given a new name (like fg_strcmp()). If I had needed file I/O I would have had to go directly to DOS and bypass the standard runtime library. The math library (sin(), pow(), etc) would be a major code size hit if it had been necessary to duplicate them. Fortunately my application didn't need this. Another major thing to watch out for is memory allocation. Do you need malloc() and siblings? Walter built in support for special versions in the runtime libraries for this, but it wouldn't be difficult for third party vendors to have their users supply the hooks for this. I explain this with the hope that more third party vendors to support more compilers (especially Zortech of course). It wasn't really that hard, and all the strange stuff (patchobj) is handled in the makefile once it is figured out. -- joe@proto.com uunet!proto!joe FAX: 208-263-8772