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 **