TweetFollow Us on Twitter

Carbonization 101 Volume Number: 16 (2000)
Issue Number: 12
Column Tag: Carbon Development

Carbonization 101

By Éric Simenel

Easier than you might think and so rewarding

The Benefits of Carbon

A beta version of Mac OS X has just been released to the public and a final version should be released in early 2001.


Figure 1. Mac OS X applications.

Four different kinds of applications, shown in Figure 1, can run on Mac OS X:

  1. unmodified Mac OS applications currently running on Mac OS 9 or earlier, will run in the Classic environment. The User Experience will be the same as the one provided with Mac OS 9, and if one of the applications running in that environment encounters a serious problem, it may bring down the whole environment and thus any other application running in that environment.
  2. Java applications, developed using only the JDK and companion libraries.
  3. Cocoa applications, developed in either java or Objective-C (possibly mixed with C/C++), and using the Cocoa frameworks.
  4. and, last but not least, Carbon applications which are slightly modified Mac OS applications.

Each of the last three kinds of application, Java, Cocoa, and Carbon, all run as separate processes in their own protected memory area. If any of those applications encounters a serious problem, it won't affect the others.

The benefits, then, of Carbonizing an application should be apparent: for the cost of a few hours or days of work, you get a much more robust and impervious application that your users can run without problems. Another advantage is that a carbonized application gives you the Aqua theme user interface on Mac OS X.

Carbon being present, through the installation of CarbonLib, on Mac OS 9, 8.6, and 8.1, a Carbonized application, as a single binary, can run on all Mac OS from 8.1 to X.

The Scope of Carbon

Most applications and some plug-ins can be carbonized successfully. Extensions (INITs), Control Panels (cdev), and drivers of any sort cannot be carbonized since they don't run on Mac OS X and the main goal of Carbon is to provide an easy transition for developers from Mac OS 8 and 9 to Mac OS X.

Which version of Carbon should be used?

The version of Carbon that you choose depends on your goals and the configurations that you are targeting. If you want the maximum Mac OS coverage, use only Carbon 1.0.4 APIs which are supported from Mac OS 8.1 to Mac OS X. CarbonLib 1.0.4 gives most of the Toolbox APIs, plus the Control, Window, and Menu Properties, Navigation Services, the Core Foundation APIs, and Carbon Printing 1.0. If, when carbonizing, you find that you are missing a desired functionality, check if it is provided in the Carbon 1.1 APIs which give you access to Appearance 1.1, Carbon Events (which offer an alternative to patching the Toolbox), the new DataBrowser control, ATSUI, URL Access, Keychain, FontSync, XML, HTMLRenderingLib, and others. Choosing the Carbon 1.1 APIs will restrict your target configurations to Mac OS 8.6 and above.

Note: Carbon on Mac OS X, and its companion CarbonLib for Mac OS 8 and 9, are not a closed API but an ongoing development. Future Apple technologies might be delivered only through the Carbon APIs.

The Carbon Porting Process

Let's examine the nuts-and-bolts to see how porting to Carnon can be done. The goal of this article is not to be a rewrite of the "Carbon Porting" document which can be found in the Carbon SDK (see the bibliography at the end of the article for useful URLs), but rather a step-by-step guide based on DTS Engineers' experiences during various Carbon Porting lab events with 3rd-party developers at Apple.

This is not just a bunch of recipes, although you may find them very useful, but rather a methodology to apply when you encounter a problem not yet covered in any documentation.

Estimating how much work will be required

Of course, the amount of work depends on the size of the source code and the number of unsupported APIs in your source code. Experience in the Carbon Porting labs tells us that most developers can successfully carbonize 80% or more of their applications in the 3 to 5 days of that event.

CarbonDater is a tool which may help you quickly determine the amount of work to be done. An example of a Carbon Compatibility Report is shown in Figure 2.


Figure 2. The Carbon Compatibility Report.

The Carbon Compatibility Report also provides a fairly detailed analysis and some suggestions as to how to replace unsupported APIs (Figure 3) and the kinds of modifications you will have to make in order to be Carbon-compliant (Figure 4).


Figure 3. Unsupported API.


Figure 4. Modified API.

Another way to estimate the necessary amount of time is to plunge right into the Carbonization process; the first compilation will give you an idea of the extent of the work to be done.

First things first

As the "Carbon Porting Guide" suggests, it's best to update your project to the latest Universal Headers first. If you're interested in Carbon 1.0, then use the Universal Headers 3.3.2, but if you're interested in Carbon 1.1, then use the Universal Headers 3.4. If you are developing with CodeWarrior, be careful to follow the instructions (from your CodeWarrior User's manual) and update any pre-compiled headers if you're using them.

The next step depends on the size of your project and the way you prefer to develop. You can either follow all the steps described in the "Carbon Porting Guide" (which is preferable if your project is large), or follow these instructions (which assume you are using CodeWarrior, any version after and including Pro 2):

  • first, clone your existing PowerPC target,
  • second, add the preprocessor command #define TARGET_API_MAC_CARBON 1 to the beginning of your project's prefix file (if you already have a prefix file, then duplicate it, add the preprocessor command in one of them and use this one for your Carbon target),
  • and third, remove all Apple stub libraries such as InterfaceLib and any others that you might have needed in your project such as AppearanceLib, WindowsLib, etc., and add the CarbonLib stub instead. You can keep non-Apple libraries such as "MSL RuntimePPC.Lib", "MSL C.PPC.Lib", etc.

If you are using any other libraries, then you will need to determine (the PEF Viewer utility can help you do that) if the code they contain is importing any symbols from InterfaceLib or any of those Apple libraries at runtime. If that's not the case then they should be safe to use as is, but if they are , then those libraries will have to be carbonized as well.

After you're finished with those 3 steps, which shouldn't take you more than a few minutes, then attempt your first build.

You will get many, perhaps thousands, of errors.

Luckily, 80% of them, if not more, are repeats and just illegal access to Toolbox structures which are now opaque or illegal type usage (DialogPtr, WindowPtr, and GrafPtr are now 3 different pointer types and can't be used in place of each other). Addressing those errors is simple but tedious, and it just takes time. There are 2 different ways to fix those errors, one involving the CarbonAccessors.o library, and the other one involving conditional compilation. For instance, the following extract, which should be quite common in your source code:

   WindowPtr theWind;
   ...
   SetPort(theWind);

is going to generate the compiler error:

Error:
cannot convert 'OpaqueWindowPtr *' to 'OpaqueGrafPtr *'

You can either change the source code to

   SetPortWindowPort(theWind);

and add the CarbonAccessors.o library to your non-Carbon targets in your project or change the source code to

#if !TARGET_API_MAC_CARBON
   SetPort(theWind);
#else
   SetPortWindowPort(theWind);
#endif

and you don't have to add the library.

The advantage of the former solution is that the source code is more readable but your non-Carbon application is going to grow by about 60K, whereas the advantage of the latter is that your non-Carbon application stays rigorously the same, but you will have to add a lot of those #if !TARGET_API_MAC_CARBON lines in your source code which can also look like:

#if !TARGET_API_MAC_CARBON
   yLocation = theWind->portRect.bottom-10;
#else
   Rect thePortRect;
   GetWindowPortBounds(theWind, &thePortRect);
   yLocation = thePortRect.bottom-10;
#endif

It's your choice.

Finding out Carbon information

The best way to find out is to apply the following methodology: in the previous example, you tried to access the portRect field of the WindowPtr theWind. This is doubly illegal because the variable theWind is a WindowPtr and not a GrafPtr, and also because both WindowPtr and GrafPtr are opaque structures anyway. So the obvious solution is to look at the GrafPort structure definition in QuickDraw.h and there you will see that it changed to:

struct GrafPort {
   short device;   /* not available in Carbon*/
   BitMap portBits;   /* in Carbon use GetPortBitMapForCopyBits 
      or IsPortColor*/
   Rect portRect;   /* in Carbon use Get/SetPortBounds*/
   ...
   };

and if you look for GetPortBounds you will find it at the end of QuickDraw.h in the /* Getters */ section:

EXTERN_API( Rect *)
   GetPortBounds(CGrafPtr port, Rect * rect);

So now you know how to get the portRect out of a GrafPtr (or a CGrafPtr, both are equivalent in Carbon since the structures they point to are opaque), but what you have is a WindowPtr. Again, since the port of the window is in fact a field in the WindowRecord structure you just open MacWindows.h and you look at the WindowRecord (or CWindowRecord) structure definition and there you will see that it changed to:

struct WindowRecord {
   GrafPort port;   /* in Carbon use GetWindowPort*/
   short windowKind;   /* in Carbon use Get/SetWindowKind*/
   ...
   };

And if you look for GetWindowPort you will find it at the end of MacWindows.h in the /* Getters */ section (do you see a pattern here?):

EXTERN_API( CGrafPtr ) GetWindowPort(WindowRef window);

Don't worry about the WindowRef type which is the same as WindowPtr (defined in QuickDraw.h for practical reasons).

So you could write:

#if !TARGET_API_MAC_CARBON
   yLocation = theWind->portRect.bottom-10;
#else
   Rect thePortRect;
   CGrafPtr theWindowPort;
   theWindowPort = GetWindowPort(theWind);
   GetPortBounds(theWindowPort, &thePortRect);
   yLocation = thePortRect.bottom-10;
#endif

but, in order to simplify and reduce the coding, Apple also provided a direct GetWindowPortBounds call that you also find at the end of MacWindows.h:

EXTERN_API( Rect *)
   GetWindowPortBounds(WindowRef window, Rect * bounds);

so that's why you can write the shorter code shown in the previous section. Apple provided those shortcuts for the most common usage.

Since the GetWindowPortBounds call (like the others) returns the same Rect* as being passed as the second parameter, you could even write:

#if !TARGET_API_MAC_CARBON
   yLocation = theWind->portRect.bottom-10;
#else
   Rect thePortRect;
   yLocation = 
      GetWindowPortBounds(theWind, &thePortRect)->bottom-10;
#endif

or even, if you keep a global scratch variable Rect gTempRect around which will be used for such operations you could write:

#if !TARGET_API_MAC_CARBON
   yLocation = theWind->portRect.bottom-10;
#else
   yLocation = 
      GetWindowPortBounds(theWind, &gTempRect)->bottom-10;
#endif

Again, it's your choice.

Sometimes, the comments provided in the Header files for Carbonization advice are not on the same line as the information you're looking for, but usually they're not too far away. In the following case for example:

   GrafPtr currentPort;
   GetPort(&currentPort);
   EraseRect(&currentPort->portRect);
   InvalRect(&currentPort->portRect);

will bring you:

Error : undefined identifier 'portRect'
SampleWindows.cp line 336 EraseRect(&currentPort->portRect);
Error : undefined identifier 'InvalRect'
SampleWindows.cp line 337 InvalRect(&currentPort->portRect);

The incorrect usage of portRect will be fixed by a simple call to GetPortBounds as previously but what about InvalRect? A search for InvalRect (in MacWindows.h) will make apparent that we now have:

#if CALL_NOT_IN_CARBON
EXTERN_API( void ) InvalRect(const Rect * badRect) ONEWORDINLINE(0xA928);
...
#endif   /* CALL_NOT_IN_CARBON */

so we have to look around and we will see that for this call as well as for InvalRgn, ValidRect, and ValidRgn, we have a comment above which says:

/*
   These aren't present in Carbon. Please use the InvalWindowRect, etc. routines
   below instead.
*/

So we will diligently replace the illegal code with:

   Rect thePortRect;
   GetPortBounds(currentPort, &thePortRect);
   EraseRect(&thePortRect);
   InvalWindowRect(GetWindowFromPort(currentPort), 
                        &thePortRect);

You will note that we also used the utility function GetWindowFromPort which you can find in MacWindows.h as well.

What happened to my qd?

The global variable qd has been removed so if you had been using some code like:

   DragWindow(theWind, theEvent->where, 
                  &qd.screenBits.bounds);

then, after looking for screenBits in QuickDraw.h and finding the relevant comment, you will have to write:

   Rect bounds;
#if !TARGET_API_MAC_CARBON
   bounds = qd.screenBits.bounds;
#else
   BitMap bmap;
   GetQDGlobalsScreenBits(&bmap);
   bounds = bmap.bounds;
#endif
   DragWindow(theWind, theEvent->where, &bounds);

What happened to my InitGraf and other Toolbox Managers Initialization calls?

Most of them are now just unneeded in Carbon so you can just conditional-compile out InitGraf, InitFonts, InitWindows, InitMenus, TEInit, and InitDialogs. You must still use InitCursor. Typical initialization memory schemes such as the manipulation of the heap limit (SetApplLimit and GetApplLimit) as well as MaxApplZone are also prohibited in Carbon.

For obsolescence reasons, the support for Desk Accessories is no longer required in applications so SystemClick and OpenDeskAcc have also been removed from Carbon.

So is it just searching, finding, and replacing?

Although at least 80% or more of the errors you will get at the first compilation will indeed be no more problematic than that, still it's not going to be that simple for the remaining 20% or less.

First you have to deal with the modified calls such as NewCWindow (and NewWindow, NewDialog, and NewColorDialog as well for the same reason) which does not accept a storage parameter anymore. Unfortunately the compiler will not alert you that such calls are going to fail although you will get a null return value from the call so if you have a good error-checking code you will easily detect the problem at runtime rather than crashing. The main reason developers were passing a storage as first parameter is that they wished to extend the Toolbox structure with their own fields, and to lessen heap fragmentation. Since those structures are opaque, this is no longer possible. So you will have to modify such declarations:

Note: All error-checking code has been removed from the sample code extracts present in this article so that the modifications you have to apply in order to Carbonize are more evident. Real code would need error-checking...

typedef struct
   {
   WindowRecord theWind;
   OSType theSignature;
   GWorldPtr theGWorld;
   ...
   } MyWind, *MyWindPtr;

in

typedef struct
   {
#if ! TARGET_API_MAC_CARBON
   WindowRecord theWind;
#else
   WindowPtr theWind;
#endif
   OSType theSignature;
   GWorldPtr theGWorld;
   ...
   } MyWind, *MyWindPtr;

and change from:

   wind = (MyWindPtr)NewPtr(sizeof(MyWind));
   if (wind != 0L)
      {
      wind->theSignature = kSig;
      NewCWindow(wind, &rBounds, fName, 1, 
                     noGrowDocProc, (WindowPtr)-1L, 1, 0L);
      ...
      }

to:

   wind = (MyWindPtr)NewPtr(sizeof(MyWind));
   if (wind != 0L)
      {
      wind->theSignature = kSig;
#if ! TARGET_API_MAC_CARBON
      NewCWindow(wind, &rBounds, fName, 1, 
                     noGrowDocProc, (WindowPtr)-1L, 1, 0L);
#else
      wind->theWind = NewCWindow(NULL, &rBounds, fName, 1, 
                     noGrowDocProc, (WindowPtr)-1L, 1, (long)wind);
#endif
      ...
      }

and you can still extract your MyWind structure location from the refCon value of your WindowPtr. If you were already using the refCon field to store some other information, then you can keep that information in the structure MyWind instead. Another solution is to use the new functions SetWindowProperty and GetWindowProperty which enable to attach tagged information to any window.

Another likely modification you will have to make is the control list walk-through. Previously you could just start from the controlList field of the structure WindowRecord, but of course this field is no longer accessible in the opaque structure and there are no accessor function to retrieve it. In order to get the first control of the control list of a window, you will have to modify your code like this:

   // window creation with NewWindow, or NewCWindow, 
   // or CreateNewWindow (preferred...), or...

#if TARGET_API_MAC_CARBON
      ControlRef theRootControl;
      if (theWindow != NULL)
         CreateRootControl(theWindow, &theRootControl);
#endif

and later:

#if !TARGET_API_MAC_CARBON
   ControlHandle theControl = (ControlHandle)
      (((WindowPeek)theWindow)->controlList);
   while (theControl != NULL)
#else
   UInt16 numChildren, index;
   ControlRef rootControl, theControl;
   GetRootControl(theWindow, &rootControl);
   CountSubControls(rootControl, &numChildren);
   for (index = numChildren; index >= 1; index—)
#endif
      {
#if TARGET_API_MAC_CARBON
      GetIndexedSubControl(rootControl, index, &theControl);
#endif
      // do something with theControl,
      // you can even dispose it since we're doing a reverse loop
#if !TARGET_API_MAC_CARBON
#if DISPOSINGCONTROL
      theControl = (ControlHandle)
         (((WindowPeek)theWindow)->controlList);
#else
      theControl = (*theControl)->nextControl;
#endif
#endif
      }

If you didn't add support for the Navigation Services, to replace the use of the Standard File Package, now is the time since Carbon does not support the Standard File Package.

Another whole section of the traditional Macintosh Toolbox, the Scrap Manager, has also been revised in Carbon. Most applications use the Scrap Manager routines in a fairly straightforward way and the amount of modifications you may have to apply may not be much more complicated than the following.

For copying:

#if !TARGET_API_MAC_CARBON
   ZeroScrap();
#else
   ScrapRef scrapRef;
   ClearCurrentScrap();
   status = GetCurrentScrap(&scrapRef);
#endif

#if !TARGET_API_MAC_CARBON
   PutScrap(byteLength, 'utxt', *hUnicodeText);
#else
   status = PutScrapFlavor(scrapRef, 'utxt',
      kScrapFlavorMaskNone, byteLength, *hUnicodeText);
#endif

And for pasting:

#if !TARGET_API_MAC_CARBON
   LoadScrap();
#else
   ScrapRef scrapRef;
   status = GetCurrentScrap(&scrapRef);
#endif

#if !TARGET_API_MAC_CARBON
   long offset, byteLength = GetScrap(NULL, 'utxt', &offset);
#else
   long byteLength;
   status = GetScrapFlavorSize(scrapRef, 'utxt', &byteLength);
#endif

   if (byteLength <= 0) return;

#if !TARGET_API_MAC_CARBON
   Handle hUnicodeText = NewHandle(0);
   GetScrap(hUnicodeText, 'utxt', &offset);
#endif
   
   // let's grab the text from the scrap
   UniCharCount uTextLength = byteLength / sizeof(UniChar);
   UniCharArrayPtr theUnicodeText =
      (UniCharArrayPtr)NewPtr(byteLength);

#if !TARGET_API_MAC_CARBON
   HLock(hUnicodeText);
   BlockMoveData(*hUnicodeText, (Ptr)theUnicodeText,
      byteLength);
#else
   status = GetScrapFlavorData(scrapRef, 'utxt', &byteLength,
      theUnicodeText);
#endif

Almost there since we should just comment out all the printing code for now. The Printing Manager has been revised also in Carbon and in such ways that it could be the only subject of another MacTech article by itself, so we're not going to deal with that in this article.

Patience and labor will get you to a point where you no longer get any compilation errors.

But now you'll see link errors.

Maybe some will be due to Toolbox calls present in the headers but missing in the CarbonLib shared library (this is still a work in progress), but most of the errors will come from the use of MSL (MetroWerks Standard Library). You will either have to use the updated for Carbon version of MSL from MetroWerks (which is part of CodeWarrior Pro 6 which also contains a fully carbonized version of PowerPlant) or get rid entirely of any dependencies on this package.

Again, patience and labor will get you to a point where you no longer get any link errors.

And you should thus be able to test your application on Mac OS 9 (recommended for the first runs), and it should run fine although you may have to increase the memory partition (resource 'SIZE ' id -1).

Depending on the version of CarbonLib you've been developing against, you can also test the running of your application on 8.6 and 8.1.

But the real test will of course be the running on Mac OS X!

Running on Mac OS X

If you just launch your recently carbonized application on Mac OS X, you may not see a single difference in either behavior or even appearance with your application running on Mac OS 9. The most probable cause is that you're in fact running your carbonized application in the Classic environment! If you don't see your application interface using the Aqua theme user interface, then you are running in the Classic environment. In order for your application to be run as a Carbon Application, and thus in its own memory-protected space and with the Aqua theme user interface, you have to let Mac OS X know about the fact that you did your job and carbonized this application. You do that by adding both a 'carb' resource with id 0, the content does not matter, and usually you'll just set a single byte as 0, and adding a 'plst' resource, also with id 0, which contains the XML representation of the application's property list. If those 2 resources are present in your application then Mac OS X will launch your application as a Carbon process with all the advantages that come with it.

Note: If you have been following the suggested steps described above, you should have at least 3 different targets for your project: debug-Classic, non-debug-Classic, non-debug-Carbon. Your may have more... Since all those targets can run on Mac OS X, either being launched in the Classic environment, or launched as a Carbon process, it might be useful to be able to identify at runtime, with certainty, which target you're currently running. You could use the following routines (or adapt them to your needs) to achieve identification:

Boolean IsThisX()
   {
   long response;
   OSErr err = Gestalt(gestaltSystemVersion, &response);
   return ((err == noErr) && (response >= 0x00000A00));
   }

Boolean IsThisAqua()
   {
   long response;
   OSErr err = Gestalt(gestaltMenuMgrAttr, &response);
   return
      (
         (err == noErr) &&
         ((response & gestaltMenuMgrAquaLayoutMask) != 0)
      );
   }

void DoAboutBox()
   {
   Str255 theStr, theStr2, theStr3;
#if __option (sym)
   sprintf((char *)theStr2, "Debug Version");
#else
   sprintf((char *)theStr2, "Final Version");
#endif
#if TARGET_API_MAC_CARBON
   if (IsThisAqua())
      sprintf((char *)theStr3, "Carbon Aqua");
   else
      sprintf((char *)theStr3, "Carbon Platinum");
#else
   sprintf((char *)theStr3, "Classic");
#endif
   sprintf((char *)&theStr[1], "%s, %s, %s, %s",
      (char *)theStr2, (char *)theStr3, __DATE__, __TIME__);
   theStr[0] = strlen((char *)&theStr[1]);
   ParamText(theStr, "\p", "\p", "\p"); Alert(128, 0L);
   }

When running on Mac OS X, you will notice that some system menus have changed and some menu items have moved. One important change is that the Quit menu item is now in the Application menu (which replaces the Apple menu of Mac OS 9 and previous). You are no longer supposed to have a Quit menu item in your File menu. That also means, by the way, that you need to have a QuitAppleEventHandler routine since this is the way that Mac OS X will inform your application that the user wants to quit it. You are not supposed to add the "desk accessories" (which have not been true desk accessories for a very long time anyway) in the Apple menu either.

So your menu initialization and installation routine should look like:

   Handle menuBar = GetNewMBar(kMainMenuBar);
   SetMenuBar(menuBar);
   DisposeHandle(menuBar);
#if TARGET_API_MAC_CARBON
   if (IsThisAqua()) // removing the Quit menu item and the separator line
      {
      MenuHandle menu = GetMenuHandle(kFileMenu);
      DeleteMenuItem(menu, kQuitMenuItem);
      DeleteMenuItem(menu, kQuitMenuItem-1);
      }
#else
   AppendResMenu(GetMenuHandle(kAppleMenu), 'DRVR');
#endif
   DrawMenuBar();

And with that fine-tuning achieved, you are pretty much done. You will still have to thoroughly test your application on all Mac OS versions it's supposed to run on, but the job is no more complicated than described here (with the exception of printing which has to be rewritten). You may encounter some mysterious behaviors and the most frequently reported is that the drawing in one of your windows is not happening anymore (typically some kind of animation). The most likely reason for that is that you are drawing in that window outside of its update routine and since windows are double-buffered on Mac OS X, you just keep modifying the bits of the offscreen and nothing happens in the window on the screen. Carbon moves the bits from the offscreen to the window at the end of the update routine and in some other conditions, but not in that case, so you will have to add a bit of tweaking there as well. There are 2 ways to achieve that tweaking, but only one is recommended. QuickDraw.h provides 3 new APIs (QDIsPortBuffered, QDIsPortBufferDirty, and QDFlushPortBuffer) which can be used that way:

   InitTheCircle();
   for (i=startingMonth; i<=endingMonth; i++)
      {
      UnsignedWide startingTime, endingTime;
      Microseconds(&startingTime);
      UpdateTheCircle(i);

      /* on Mac OS X, drawing is double-buffered by default*/

#if TARGET_API_MAC_CARBON
      if (QDIsPortBuffered((CGrafPtr)curPort))
         QDFlushPortBuffer((CGrafPtr)curPort, NULL);
#endif
      do {Microseconds(&endingTime);} while
         (ComputeMicros(&startingTime, &endingTime) <
            kAnimationDelay);
      }
  TermTheCircle();

The other way, which is not recommended, is to add the kWindowNoBufferingAttribute attribute to the WindowAttributes parameter you pass to CreateNewWindow. In that case, the window will not be double-buffered so all drawing will be directed to the window, but you disrupt the normal updating mechanism of the Window Server and, for instance, if you move such a window, you may leave undesirable graphical artifacts on your screen.

Conclusion

If you have more than one application to carbonize, we advise you to start with the most recently developed first since it will be the easiest to carbonize. It should already be using a recent version of the Universal Headers and shouldn't do too many of the various no-no's no longer available in Carbon. Going back in time, carbonizing older and older applications, you will find that the previous experiences will help you to overcome the difficulties arising from carbonizing old code. But the methodology remains the same:

  1. use at least the Universal Headers 3.3.2
  2. for each error, refer to that routine or that structure in the appropriate header and read the Carbonization comments which are sure to be found around.

If for any reason you are at a loss as to what to do or how to do it, then you're more than welcome to join and participate in the Carbon Development mailing list that you can join by sending an email to <requests@sam.apple.com> with "subscribe carbon_development" as the email's message. The Carbon Development mail list is restricted to discussion of Carbon development issues.

If you still can't find satisfaction when participating in the list, you can address your question to <dts@apple.com> but you need to be a member of our programs in order to do that.

References


Éric Simenel simenel.e@apple.com is a software engineer in Apple's DTS (Developer Technical Support) team. He is currently supporting Mac OS 9 and Carbon.

 
AAPL
$102.50
Apple Inc.
+0.25
MSFT
$45.43
Microsoft Corpora
+0.55
GOOG
$571.60
Google Inc.
+2.40

MacTech Search:
Community Search:

Software Updates via MacUpdate

Skype 6.19.0.450 - Voice-over-internet p...
Skype allows you to talk to friends, family and co-workers across the Internet without the inconvenience of long distance telephone charges. Using peer-to-peer data transmission technology, Skype... Read more
VueScan 9.4.41 - Scanner software with a...
VueScan is a scanning program that works with most high-quality flatbed and film scanners to produce scans that have excellent color fidelity and color balance. VueScan is easy to use, and has... Read more
Cloud 3.0.0 - File sharing from your men...
Cloud is simple file sharing for the Mac. Drag a file from your Mac to the CloudApp icon in the menubar and we take care of the rest. A link to the file will automatically be copied to your clipboard... Read more
LibreOffice 4.3.1.2 - Free Open Source o...
LibreOffice is an office suite (word processor, spreadsheet, presentations, drawing tool) compatible with other major office suites. The Document Foundation is coordinating development and... Read more
SlingPlayer Plugin 3.3.20.505 - Browser...
SlingPlayer is the screen interface software that works hand-in-hand with the hardware inside the Slingbox to make your TV viewing experience just like that at home. It features an array of... Read more
Get Lyrical 3.8 - Auto-magically adds ly...
Get Lyrical auto-magically add lyrics to songs in iTunes. You can choose either a selection of tracks, or the current track. Or turn on "Active Tagging" to get lyrics for songs as you play them.... Read more
Viber 4.2.2 - Send messages and make cal...
Viber lets you send free messages and make free calls to other Viber users, on any device and network, in any country! Viber syncs your contacts, messages and call history with your mobile device,... Read more
Cocktail 7.6 - General maintenance and o...
Cocktail is a general purpose utility for OS X that lets you clean, repair and optimize your Mac. It is a powerful digital toolset that helps hundreds of thousands of Mac users around the world get... Read more
LaunchBar 6.1 - Powerful file/URL/email...
LaunchBar is an award-winning productivity utility that offers an amazingly intuitive and efficient way to search and access any kind of information stored on your computer or on the Web. It provides... Read more
Maya 2015 - Professional 3D modeling and...
Maya is an award-winning software and powerful, integrated 3D modeling, animation, visual effects, and rendering solution. Because Maya is based on an open architecture, all your work can be scripted... Read more

Latest Forum Discussions

See All

Rhonna Designs Magic (Photography)
Rhonna Designs Magic 1.0 Device: iOS Universal Category: Photography Price: $1.99, Version: 1.0 (iTunes) Description: Want to sprinkle *magic* on your photos? With RD Magic, you can add colors, filters, light leaks, bokeh, edges,... | Read more »
This Week at 148Apps: August 25-29, 2014
Shiny Happy App Reviews   | Read more »
Qube Kingdom – Tips, Tricks, Strategies,...
Qube Kingdom is a tower defense game from DeNA. You rally your troops – magicians, archers, knights, barbarians, and others – and fight against an evil menace looking to dominate your kingdom of tiny squares. Planning a war isn’t easy, so here are a... | Read more »
Qube Kingdom Review
Qube Kingdom Review By Nadia Oxford on August 29th, 2014 Our Rating: :: KIND OF A SQUARE KINGDOMUniversal App - Designed for iPhone and iPad Qube Kingdom has cute visuals, but it’s a pretty basic tower defense game at heart.   | Read more »
Fire in the Hole Review
Fire in the Hole Review By Rob Thomas on August 29th, 2014 Our Rating: :: WALK THE PLANKUniversal App - Designed for iPhone and iPad Seafoam’s Fire in the Hole looks like a bright, 8-bit throwback, but there’s not enough booty to... | Read more »
Alien Creeps TD is Now Available Worldwi...
Alien Creeps TD is Now Available Worldwide Posted by Ellis Spice on August 29th, 2014 [ permalink ] Universal App - Designed for iPhone and iPad | Read more »
Dodo Master Review
Dodo Master Review By Jordan Minor on August 29th, 2014 Our Rating: :: NEST EGGiPad Only App - Designed for the iPad Dodo Master is tough but fair, and that’s what makes it a joy to play.   | Read more »
Motorsport Manager Review
Motorsport Manager Review By Lee Hamlet on August 29th, 2014 Our Rating: :: MARVELOUS MANAGEMENTUniversal App - Designed for iPhone and iPad Despite its depth and sense of tactical freedom, Motorsport Manager is one of the most... | Read more »
Motorsport Manager – Beginner Tips, Tric...
The world of Motorsport management can be an unforgiving and merciless one, so to help with some of the stress that comes with running a successful race team, here are a few hints and tips to leave your opponents in the dust. | Read more »
CalPal Update Brings the App to 2.0, Add...
CalPal Update Brings the App to 2.0, Adds Lots of New Stuff Posted by Ellis Spice on August 29th, 2014 [ permalink ] | Read more »

Price Scanner via MacPrices.net

Apple now offering refurbished 21-inch 1.4GHz...
The Apple Store is now offering Apple Certified Refurbished 21″ 1.4GHz iMacs for $929 including free shipping plus Apple’s standard one-year warranty. Their price is $170 off the cost of new models,... Read more
Save $50 on the 2.5GHz Mac mini, on sale for...
B&H Photo has the 2.5GHz Mac mini on sale for $549.99 including free shipping. That’s $50 off MSRP, and B&H will also include a free copy of Parallels Desktop software. NY sales tax only. Read more
Save up to $300 on an iMac with Apple refurbi...
The Apple Store has Apple Certified Refurbished iMacs available for up to $300 off the cost of new models. Apple’s one-year warranty is standard, and shipping is free. These are the best prices on... Read more
The Rise of Phablets
Carlisle & Gallagher Consulting Group, a businesses and technology consulting firm focused solely on the financial services industry, has released an infographic depicting the convergence of... Read more
Bad Driver Database App Allows Good Drivers t...
Bad Driver Database 1.4 by Facile Group is a new iOS and Android app that lets users instantly input and see how many times a careless, reckless or just plain stupid driver has been added to the... Read more
Eddy – Cloud Music Player for iPhone/iPad Fre...
Ukraine based CapableBits announces the release of Eddy, its tiny, but smart and powerful cloud music player for iPhone and iPad that allows users to stream or download music directly from cloud... Read more
A&D Medical Launches Its WellnessConnecte...
For consumers and the healthcare providers and loved ones who care for them, A&D Medical, a leader in connected health and biometric measurement devices and services, has launched its... Read more
Anand Lal Shimpi Retires From AnandTech
Anand Lal Shimpi, whose AnandTech Website is famous for its meticulously detailed and thoroughgoing reviews and analysis, is packing it in. Lal Shimpi, who founded the tech site at age 14 in 1997,... Read more
2.5GHz Mac mini, Apple refurbished, in stock...
The Apple Store has Apple Certified Refurbished 2.5GHz Mac minis available for $509, $90 off MSRP. Apple’s one-year warranty is included, and shipping is free. Read more
13-inch 2.5GHz MacBook Pro on sale for $999,...
B&H Photo has the 13″ 2.5GHz MacBook Pro on sale for $999.99 including free shipping plus NY sales tax only. Their price is $100 off MSRP. Read more

Jobs Board

*Apple* Retail - Multiple Positions (US) - A...
Sales Specialist - Retail Customer Service and Sales Transform Apple Store visitors into loyal Apple customers. When customers enter the store, you're also the Read more
*Apple* Retail - Multiple Positions (US) - A...
Sales Specialist - Retail Customer Service and Sales Transform Apple Store visitors into loyal Apple customers. When customers enter the store, you're also the Read more
*Apple* Retail - Multiple Positions (US) - A...
Sales Specialist - Retail Customer Service and Sales Transform Apple Store visitors into loyal Apple customers. When customers enter the store, you're also the Read more
*Apple* Retail - Multiple Positions (US) - A...
Sales Specialist - Retail Customer Service and Sales Transform Apple Store visitors into loyal Apple customers. When customers enter the store, you're also the Read more
Senior Event Manager, *Apple* Retail Market...
…This senior level position is responsible for leading and imagining the Apple Retail Team's global event strategy. Delivering an overarching brand story; in-store, Read more
All contents are Copyright 1984-2011 by Xplain Corporation. All rights reserved. Theme designed by Icreon.