How To Build a Code Resource (129787)



The information in this article applies to:

  • Microsoft Visual C++, Macintosh Cross-Development Addon 4.0

This article was previously published under Q129787

SUMMARY

You can use Visual C++ to build Code Resources of type CDEF, cdev, INIT, LDEF, MDEF, WDEF, and XCMD. This article illustrates how.

MORE INFORMATION

Applications use the register A5 to point to their global memory and as a base for intersegment jumps. Stand-alone Code Resources cannot use A5 in this manner. To use global memory in Visual C++, follow these steps:

  1. Locate the entry points for the Code Resource types (CDEF, cdev, INIT, LDEF, MDEF, WDEF, and XCMD) at the beginning of the resource. When Visual C++ compiles a code resource, it locates the global data at the beginning of the resource by default. To force the global data to be moved to the end of the resource use the code_seg pragma as in this example:
       #pragma code_seg("MAIN$2")
    						
    This forces any declarations that follow to be placed in the second half of the MAIN Code Resource. The data is referenced as an offset from the PC register, rather than the A5 register.
  2. To avoid an intersegment jump, merge the code from two segments together by using the Linker's MERGE option. This step is necessary if a Code Resource calls into a library such as the C Runtime libraries because a second segment is created and the call to the function becomes an intersegment jump.

    For example, if the C Runtime library is being merged with and INIT titled MAIN, add the following line to the Link:Project Options found in the Project Settings dialog:

    MERGE:CRTSTRING?=MAIN Replace the question mark (?) with an ASCII character 1. The CRTSTRING? segment is titled CRTSTRIN by the Linker, so the name of the segments in the target application cannot be used. To determine the name of any segments generated by Visual C++, build the Code Resource as a 'CODE' resource first. Then check the .MAP file for the correct spelling of the segment.

    If a Code Resource is built without merging the segments the following Linker error is generated: error LNK1574: A5 reference to SomeFunction invalid in standalone code

Sample Code

Here is a sample INIT Code Resource including code and project settings:

The C/C++ Project Options:

   /nologo /W3 /YX /Oi /D "_WINDOWS" /D "_MAC" /D "_68K_" /D "NDEBUG" /D
   "_MBCS"
    /FR"MacRel/" /Fp"MacRel/CodRes.pch" /Fo"MacRel/" /c
				
The Link Project Options:
   libcs.lib /NOLOGO /MAC:bundle /MAC:type="rsrc" /MAC:creator="RSED"
    /PDB:"MacRel/CodRes.pdb" /MAP:"MacRel/SACODE.map" /DEBUG /MACHINE:M68K
    /NODEFAULTLIB:"swapd.lib" /NODEFAULTLIB /OUT:"MacRel/CODRES.exe"
   /entry:main
    /section:MAIN,,resource="INIT"@99 /MERGE:CRTSTRING =MAIN
				
The code for this sample:
   #include <string.h>
   #include <macos\osutils.h>
   #pragma code_seg("MAIN$2")
   char _declspec(allocate("_CODE")) java[10] =" Help Me!";
   #pragma code_seg("MAIN$1")
   void main(void)
      {
      char   bob[10];
      bob[0]=0;
      strcpy(bob,java);
      DebugStr(_c2pstr(bob));
      }
				
This code creates an INIT with a resource ID of 99. There will also be resources of DATA, CODE, and MSCV. They are not needed for this Code Resource to function.

Modification Type:MinorLast Reviewed:6/29/2004
Keywords:kbcode kbhowto KB129787