[comp.sys.mac.programmer] ThinkC prototypes and Str255 args

fri0@quads.uchicago.edu (Christian E. Fritze) (09/15/90)

I'm using ThinkC's Class libraries with the Check Prototypes option set.

I'd like to be able to call functions which expect arguments of the tye Str255
with a string I build on the fly. If I try to pass a string to a function like

SomeFunction("\pHere's my string");

and the compiler expects a Str255 as an argument, I get a compile error saying
that the argument doesn't match the prototype. I don't want to muck with the
prototypes in the TCL classes for reasons of conformity with future releases,
yet the prototyper helps in so many other situations. Anyone have a good
work-around for this? Am I missing an obvious solution? Many thanks.

Chris
fri0@midway.uchicago.edu

ar4@sage.cc.purdue.edu (Piper Keairnes) (09/16/90)

fri0@quads.uchicago.edu (Christian E. Fritze) writes:
>I'd like to be able to call functions which expect arguments of the type Str255
>with a string I build on the fly. If I try to pass a string to a function like
>SomeFunction("\pHere's my string");

There is one problem... C passes arguments by value. So, when you make a
call to some procedure that expects a Str255, it is expecting the entire
string array. When you make a call such as the one above, C is simply
passing a pointer to that string.

The workaround: Make and use a procedure like the one below...
Call like you want to... SomeFunction2("\pHere's my string");

SomeFunction2(s)
	char *s;
{
	int i;
	Str255 theString;        /* you may want to have some error detection */

	theString[0] = s[0];              /* copy length byte    */
	for (i=1; i<=theString[0]; i++)   /* copy rest of string */
		theString[i] = s[i];

	SomeFunction(theString);
}

All that this function does is takes your string literal and stores it in a
variable of type Str255 then calls the intended function with that variable.
You can do this yourself in your code, or make a small function like
above to handle the interface and keep you code a little cleaner. This is
what we get for programming in C on a machine that was written in Pascal!

Please don't flame my code, I wrote it on the fly while reading news.

-----
Piper Keairnes - Computer Science   ** Purdue University Computing Center **
INTERNET: ar4@sage.cc.purdue.edu    **  Unisys Corporation Co-op Student  **
  BITNET: xar4@purccvm.bitnet       **  Macintosh Programmer/ Specialist  **

d88-jwa@dront.nada.kth.se (Jon W{tte) (09/16/90)

In article <4449@sage.cc.purdue.edu> ar4@sage.cc.purdue.edu (Piper Keairnes) writes:

>There is one problem... C passes arguments by value. So, when you make a
>call to some procedure that expects a Str255, it is expecting the entire
>string array. When you make a call such as the one above, C is simply

Oh, no, it doesn't ! Arrays are passed by reference in C,
that's why

{
	char * moof;
	char foom[];

	moof = foom;
	function(moof);
}

is equivalent with

...
	function(foom);

If you cast to void *, things will run smoothly...

>All that this function does is takes your string literal and stores it in a
>variable of type Str255 then calls the intended function with that variable.
>You can do this yourself in your code, or make a small function like
>above to handle the interface and keep you code a little cleaner. This is
>what we get for programming in C on a machine that was written in Pascal!

Check that again after you've got some sleep. A single cast will do !

								h+

	Jon W{tte, Stockholm, Sweden, h+@nada.kth.se

lippin@ragu.berkeley.edu (The Apathist) (09/16/90)

Recently fri0@quads.uchicago.edu (Christian E. Fritze) wrote:
>
>I'm using ThinkC's Class libraries with the Check Prototypes option set.
>
>I'd like to be able to call functions which expect arguments of the tye Str255
>with a string I build on the fly. If I try to pass a string to a function like
>
>SomeFunction("\pHere's my string");
>
>and the compiler expects a Str255 as an argument, I get a compile error saying
>that the argument doesn't match the prototype.

Str255 is an array of unsigned char, while string literals and
probably the string you built on the fly are arrays of signed char.  I
recommend using a cast to StringPtr for the literals, and using
Str255/StringPtr/unsigned char[] for building your own strings.  You
can avoid the cast entirely by not using string literals -- put them
in resources instead.  (Well, not entirely -- I do, but I rewrote the
prototypes for GetNamedResource and Get1NamedResource to take char *.)

The bright side to this is that pointers to pascal strings and C
strings can't be confused; you have to use an explicit cast to get the
signedness right.

					--Tom Lippincott
					  lippin@math.berkeley.edu

		"A repo man's life is always intense."
					--"Repo Man"

russotto@eng.umd.edu (Matthew T. Russotto) (09/18/90)

In article <4449@sage.cc.purdue.edu> ar4@sage.cc.purdue.edu (Piper Keairnes) writes:
>fri0@quads.uchicago.edu (Christian E. Fritze) writes:
>>I'd like to be able to call functions which expect arguments of the type Str255
>>with a string I build on the fly. If I try to pass a string to a function like
>>SomeFunction("\pHere's my string");
>
>There is one problem... C passes arguments by value. So, when you make a
>call to some procedure that expects a Str255, it is expecting the entire
>string array. When you make a call such as the one above, C is simply
>passing a pointer to that string.

If Str255 is defined as a struct, this is true.   However, in most C's,
Str255 is defined as an array (I believe MPW 2.0.x is the only exception),
and any function which accepts a parameter of type Str255 expects a pointer
to the string.

flames | the guy responsible for MPW 2.0 struct Str255s.
--
Matthew T. Russotto	russotto@eng.umd.edu	russotto@wam.umd.edu
      .sig under construction, like the rest of this campus.

ar4@sage.cc.purdue.edu (Piper Keairnes) (09/18/90)

To clear up Str255 matters...

Kernighan & Ritchie: "In C, all function arguments are passed 'by value'"
For arrays, if only the name of the array is specified as an argument then
the value of the address of the array is passed. To quote further,
"..there is no copying of array elements."

Here is the definition of Str255 and StringPtr for ThinkC v4.0:

	typedef unsigned char Str255[256];
	typedef unsigned char * StringPtr,** StringHandle ;

In a previous posting, I described a way of getting around the Str255
prototype problem. The code I gave did not consider that Str255 is simply
a unsigned char *. So, in order pass a Str255 string literal, all that must
be done is...

	SomeFunction((StringPtr) "\pSome String");

Explanation...
First off, you (and I) might try to typecast with (Str255). This is an
illegal typecast. You may notice, however, that a reference to a variable of
type Str255 without subscripts is simply an unsigned char *. So, you can
typecast the string as a (StringPtr) which is of type unsigned char *. Now,
the compiler sees that two unsigned char *'s match up and it will go on
without a problem.

This is all just some of the fun we have when mixing C and Pascal
definitions.... Sorry if my earlier post confused/upset anyone.

_____
Piper Keairnes - Computer Science   ** Purdue University Computing Center **
INTERNET: ar4@sage.cc.purdue.edu    **  Unisys Corporation Co-op Student  **
  BITNET: xar4@purccvm.bitnet       **  Macintosh Programmer/ Specialist  **