f



objc-class.h Protocol compile errors

Hi all,

I'm not sure if this appropriate as it may be an XCode or Mac OS X
specific issue.  If this post is considered off-topic, I apologize.

I'm trying to figure out a compile error I'm getting when trying to
access the objc runtime functions.  Basically, I'm taking an
interpreter and trying to tie it to the runtime.  I haven't gotten very
far, but already have a head-scratcher on my hands.

Essentially, I was going to test everything by trying to tie in the
objc_lookUpClass function.  As I understand it, this requires including
the objc-runtime.h file (which in turn calls the objc-class.h file).
So, basically that's what I did.  When I tried to compile, I got this:

/usr/include/objc/objc-class.h:171: error: syntax error at '@' token
/usr/include/objc/objc-class.h:171: error: parse error before
"Protocol"
/usr/include/objc/objc-class.h:176: error: parse error before
"Protocol"

The process stops every time at the "@class Protocol;" on line 171, and
then the Protocol list struct that comes immediately thereafter.

I'm sure it must be something I've done (or not done), but I'm not sure
what.  I've used Google several times to find something similar to my
issues, but nothing seems to be out there that specifically addresses
this situation.

Here are some project details:

The Xcode project understands this to be a command line tool, in C
I'm running GCC 3.3 on Panther (10.3.9)
This system is on a Powerbook, if that makes a difference.
This has been tried using a Makefile, and also by pulling all the
related files into a separate folder and using Xcode to build (I even
copied the objc folder containing all the objc-*.h files so that I
could try that or their standard location)
I've tried #include <objc/objc-runtime.h>, #include
"/user/include/objc/objc-runtime.h", and other variants including
#import (althought I don't know if it's supposed to be used in this
situation).
I've also tried including objc.h, objc-class.h, and objc-api.h, just in
case.  No luck there.

So there it is.  Any help would be appreciated.  Thank you for your
time!

Erik

0
Erik
11/26/2005 5:51:55 AM
comp.lang.objective-c 1160 articles. 0 followers. Post Follow

12 Replies
374 Views

Similar Articles

[PageSpeed] 11

"Erik" <groups@customvisualdesigns.com> writes:

> So, basically that's what I did.  When I tried to compile, I got this:
>
> /usr/include/objc/objc-class.h:171: error: syntax error at '@' token
> /usr/include/objc/objc-class.h:171: error: parse error before
> "Protocol"
> /usr/include/objc/objc-class.h:176: error: parse error before
> "Protocol"

Is the file that's including objc-class.h a .c file? It shouldn't be, so if
it is, rename it to .m.

sherm--

-- 
Cocoa programming in Perl: http://camelbones.sourceforge.net
Hire me! My resume: http://www.dot-app.org
0
Sherm
11/26/2005 7:02:15 AM
Sherm Pendley wrote:
> "Erik" <groups@customvisualdesigns.com> writes:
>
> > So, basically that's what I did.  When I tried to compile, I got this:
> >
> > /usr/include/objc/objc-class.h:171: error: syntax error at '@' token
> > /usr/include/objc/objc-class.h:171: error: parse error before
> > "Protocol"
> > /usr/include/objc/objc-class.h:176: error: parse error before
> > "Protocol"
>
> Is the file that's including objc-class.h a .c file? It shouldn't be, so if
> it is, rename it to .m.
>
> sherm-

Sherm,

Thanks for the advice!  It's interesting that I have to put an
Objective-C extension the the file instead of a regular C extension.
Should I try to rebuild the project as a Cocoa project, or is it just a
quirk of the system?  Should I rename all .c files to .m?

Also, the renaming gets everything to compile, but when I try to run
the interpreter and use the relevant command (to look up a class via
objc_lookUpClass), I get this:

ZeroLink: unknown symbol '_objc_lookUpClass'

So it appears to not be seeing the libobjc library.  Any thoughts would
be appreciated.

Erik

0
Erik
11/26/2005 11:25:25 PM
On 2005-11-26 15:25:25 -0800, "Erik" <groups@customvisualdesigns.com> said:

> Thanks for the advice!  It's interesting that I have to put an
> Objective-C extension the the file instead of a regular C extension.
> Should I try to rebuild the project as a Cocoa project, or is it just a
> quirk of the system?  Should I rename all .c files to .m?

This should be completely expected, and is not a "quirk of the system." 
 If you use Objective-C constructs in some code -- even including a 
header file that has some Objective-C constructs in it -- that code 
must be compiled as Objective-C rather than C.

You should not "rename all .c files to .m" -- that would be sweeping 
the issue under the rug, not understanding and addressing the issue.  
And sweeping any issues with code under the rug only makes life more 
painful in the long run -- the term "technical debt" was coined to 
describe this, because code issues accrue interest much like debt.

So, in essence, you should include Objective-C headers in Objective-C 
code, and C headers in either C or Objective-C code, as appropriate.  
You need to understand why this is and what the differences are in your 
code, and then make appropriate judgement calls.

> Also, the renaming gets everything to compile, but when I try to run
> the interpreter and use the relevant command (to look up a class via
> objc_lookUpClass), I get this:
> 
> ZeroLink: unknown symbol '_objc_lookUpClass'
> 
> So it appears to not be seeing the libobjc library.  Any thoughts would
> be appreciated.

Does your tool at link with Foundation.framework?  It should be.  
Executables generally shouldn't need to link against libobjc directly.

  -- Chris

0
Chris
11/27/2005 12:21:08 AM
Okay, I think I've misunderstood how everything is supposed to work,
here.  I had originally read in Apple's documentation that the headers
objc-class.h, objc-runtime.h, etc. were for the purpose of connecting
interpretors and such to the Objective C runtime (and to whatever
frameworks and classes exist from there).  That's why I was interested
in linking to libobjc rather than a framework.  I didn't want to
hardwire in various classes when the runtime could pick them up for me.

For some reason I was under the impression that the aforementioned
headers were C headers created to give access to the runtime (probably
because ObjC used to be a preprocessor on top of C).  So I was confused
for a bit.  What you and Sherm seem to be saying, though, is that the
headers are Objective-C headers, and that therefore, instead of trying
to create a pure C command line tool that tries (incorrectly) to access
the runtime, I should be creating a Cocoa application that somehow does
the proper connecting.  Is that correct?

Much thanks for your help,
Erik


Chris Hanson wrote:
> On 2005-11-26 15:25:25 -0800, "Erik" <groups@customvisualdesigns.com> said:
>
> > Thanks for the advice!  It's interesting that I have to put an
> > Objective-C extension the the file instead of a regular C extension.
> > Should I try to rebuild the project as a Cocoa project, or is it just a
> > quirk of the system?  Should I rename all .c files to .m?
>
> This should be completely expected, and is not a "quirk of the system."
>  If you use Objective-C constructs in some code -- even including a
> header file that has some Objective-C constructs in it -- that code
> must be compiled as Objective-C rather than C.
>
> You should not "rename all .c files to .m" -- that would be sweeping
> the issue under the rug, not understanding and addressing the issue.
> And sweeping any issues with code under the rug only makes life more
> painful in the long run -- the term "technical debt" was coined to
> describe this, because code issues accrue interest much like debt.
>
> So, in essence, you should include Objective-C headers in Objective-C
> code, and C headers in either C or Objective-C code, as appropriate.
> You need to understand why this is and what the differences are in your
> code, and then make appropriate judgement calls.
>
> > Also, the renaming gets everything to compile, but when I try to run
> > the interpreter and use the relevant command (to look up a class via
> > objc_lookUpClass), I get this:
> >
> > ZeroLink: unknown symbol '_objc_lookUpClass'
> >
> > So it appears to not be seeing the libobjc library.  Any thoughts would
> > be appreciated.
>
> Does your tool at link with Foundation.framework?  It should be.
> Executables generally shouldn't need to link against libobjc directly.
> 
>   -- Chris

0
Erik
11/27/2005 12:46:52 AM
"Erik" <groups@customvisualdesigns.com> writes:

> for a bit.  What you and Sherm seem to be saying, though, is that the
> headers are Objective-C headers

Good so far...

Those are Objective-C headers, yes, and you must be compiling Objective-C
code to use them.

> and that therefore, instead of trying
> to create a pure C command line tool that tries (incorrectly) to access
> the runtime, I should be creating a Cocoa application that somehow does
> the proper connecting.  Is that correct?

.... but you've lost me here.

The question of command-line tool vs. GUI app is entirely unrelated. And I
have no idea what you're talking about when you say "somehow does the proper
connecting" - connecting to what? Does the tool you're writing need to make
a network connection or something?

What exactly is it you want to do? If all you want is to create a command-
line tool using Objective-C, just start with the "Foundation Tool" project
template in Xcode.

The runtime functions are low-level functions for low-level tasks, like
creating a foreign language bridge, for instance. For writing ordinary apps
or command-line tools, you'll rarely (if ever) need to call them.

sherm--

-- 
Cocoa programming in Perl: http://camelbones.sourceforge.net
Hire me! My resume: http://www.dot-app.org
0
Sherm
11/27/2005 1:19:14 AM
Sherm Pendley wrote:
 What exactly is it you want to do? If all you want is to create a
command-
> line tool using Objective-C, just start with the "Foundation Tool" project
> template in Xcode.
>
> The runtime functions are low-level functions for low-level tasks, like
> creating a foreign language bridge, for instance. For writing ordinary apps
> or command-line tools, you'll rarely (if ever) need to call them.
>
> sherm--


Sorry about the confusion!  I should have been more specific.  A
foreign language bridge is what I'm going for.  I wanted to see if I
could create a bridge between a forth interpretor from
ficl.sourceforge.net to the objective-c runtime.  I thought it would be
a good learning experience if nothing else.  

Erik

0
Erik
11/27/2005 2:43:36 AM
"Erik" <groups@customvisualdesigns.com> writes:

> Sorry about the confusion!  I should have been more specific.  A
> foreign language bridge is what I'm going for.  I wanted to see if I
> could create a bridge between a forth interpretor from
> ficl.sourceforge.net to the objective-c runtime.  I thought it would be
> a good learning experience if nothing else.

The web site above indicates that Ficl is apparently geared towards easy
embedding in a compiled "host" app. So, I'd go with the flow and do that,
starting with a standard Cocoa app/tool and linking in the Ficl library
to that.

I'll talk a little bit about how CamelBones is written.

Early on, you'll want to get a list of registered classes, so you can make
them accessible from Forth. Doing that at run time instead of compile time
will allow your bridge to use *any* Objective-C classes, not just the ones
you explicitly build support for.

In CamelBones, Perl classes are registered with the runtime, so they can
participate in inheritance, etc. Registering your Forth classes is another
piece of accounting that will need to be done early.

The functions that wrap Objective-C classes and register Perl classes are
in Runtime.m in the CamelBones source.

Two bridge functions are needed, one each way.

For messages originating in Forth, there needs to be a "fallback" facility
for handling unknown methods and passing them on the Objective-C. You could
do this by using the marg_* macros and objc_msgSendv(). But there's no "v"
version of objc_msgSendSuper(), so if you intend to support inheritance and
call superclass methods from Forth, you'll need to use ffcall (or something
like it) instead of the marg_* macros.

In CamelBones, Perl->Objective-C messages are handled in NativeMethods.m.

For messages going the other way, you register your bridge function using
the class_addMethods() function. In CamelBones, every Perl method is routed
through the same function, which examines the first two arguments (self and
_cmd) to see what Perl class and method should be called.

In CamelBones, Objective-C->Perl messages are handled in PerlMethods.m.

sherm--

-- 
Cocoa programming in Perl: http://camelbones.sourceforge.net
Hire me! My resume: http://www.dot-app.org
0
Sherm
11/27/2005 4:28:10 AM
Sherm,

Thanks for the advice!  I went ahead and downloaded the source files
you mentioned in your post below.  Looking them over has given me some
food for thought.  I was originally planning on using the interpretor
to call objc_lookUpClass and just try to manually grab classes as I
needed them.  I don't know why I didn't consider objc_getClassList.
Maybe I focused on things a bit too narrowly.

In any event, thanks again for your advice.  I'm going to try and
incorporate your suggestions.  Hopefully it will put me on the right
track!

Best regards,
Erik

Sherm Pendley wrote:
> I'll talk a little bit about how CamelBones is written.
>
> Early on, you'll want to get a list of registered classes, so you can make
> them accessible from Forth. Doing that at run time instead of compile time
> will allow your bridge to use *any* Objective-C classes, not just the ones
> you explicitly build support for.
>
> In CamelBones, Perl classes are registered with the runtime, so they can
> participate in inheritance, etc. Registering your Forth classes is another
> piece of accounting that will need to be done early.
>
> The functions that wrap Objective-C classes and register Perl classes are
> in Runtime.m in the CamelBones source.
>
> Two bridge functions are needed, one each way.
>
> For messages originating in Forth, there needs to be a "fallback" facility
> for handling unknown methods and passing them on the Objective-C. You could
> do this by using the marg_* macros and objc_msgSendv(). But there's no "v"
> version of objc_msgSendSuper(), so if you intend to support inheritance and
> call superclass methods from Forth, you'll need to use ffcall (or something
> like it) instead of the marg_* macros.
>
> In CamelBones, Perl->Objective-C messages are handled in NativeMethods.m.
>
> For messages going the other way, you register your bridge function using
> the class_addMethods() function. In CamelBones, every Perl method is routed
> through the same function, which examines the first two arguments (self and
> _cmd) to see what Perl class and method should be called.
>
> In CamelBones, Objective-C->Perl messages are handled in PerlMethods.m.
> 
> sherm--

0
Erik
11/27/2005 8:05:32 AM
Erik <groups@customvisualdesigns.com> wrote:
> For some reason I was under the impression that the aforementioned
> headers were C headers created to give access to the runtime (probably
> because ObjC used to be a preprocessor on top of C).  So I was confused
> for a bit.  What you and Sherm seem to be saying, though, is that the
> headers are Objective-C headers

You don't need Sherm to tell you this. The compiler error you posted in 
your original message indicated that the compiler had found a @ character 
where it was not expected. @ is not a legal character anywhere in a C 
program, except in comments, string constants, and character constants. It 
is, however, commonly used in ObjC. This alone is enough to indicate that 
these headers are Objective-C, and must be compiled as such.

Of course, you don't compile headers directly. You #include/#import them, 
and the file that #include/#imports them gets compiled. Since the headers 
are Objective-C, any such file must be compiled as Objective-C.

> and that therefore, instead of trying
> to create a pure C command line tool that tries (incorrectly) to access
> the runtime, I should be creating a Cocoa application that somehow does
> the proper connecting.  Is that correct?

You've confused two completely unrelated issues here. One is C vs 
Objective-C, and one is command-line vs Cocoa. Cocoa is just a big 
collection of libraries that are helpful for writing apps. You can use 
ObjC without Cocoa. (But you can't use Cocoa without ObjC at least at some 
level, since that's what it's written in.) You need to use ObjC to use 
these headers. This does not imply that you need to use Cocoa, nor that 
you need to be creating a GUI application instead of a command-line tool.

-- 
Michael Ash
Rogue Amoeba Software
0
Michael
11/27/2005 12:27:20 PM
Michael,

You're right, of course.  In retrospect, I obviously misunderstood the
situation.  I suppose I have to chalk this one up to too much turkey
and eggnog on the post-thanksgiving weekend :)

I guess what happened is that the interpretor code I wanted to bridge
to the Objective-C runtime was in C, and had set up a standard tool
project, which is usually in C, so I was just thinking "C, C, C" all
the way through instead of doing the proper research into the subject.

Erik

Michael Ash wrote:
> You don't need Sherm to tell you this. The compiler error you posted in
> your original message indicated that the compiler had found a @ character
> where it was not expected. @ is not a legal character anywhere in a C
> program, except in comments, string constants, and character constants. It
> is, however, commonly used in ObjC. This alone is enough to indicate that
> these headers are Objective-C, and must be compiled as such.
>
> Of course, you don't compile headers directly. You #include/#import them,
> and the file that #include/#imports them gets compiled. Since the headers
> are Objective-C, any such file must be compiled as Objective-C.

........

> You've confused two completely unrelated issues here. One is C vs
> Objective-C, and one is command-line vs Cocoa. Cocoa is just a big
> collection of libraries that are helpful for writing apps. You can use
> ObjC without Cocoa. (But you can't use Cocoa without ObjC at least at some
> level, since that's what it's written in.) You need to use ObjC to use
> these headers. This does not imply that you need to use Cocoa, nor that
> you need to be creating a GUI application instead of a command-line tool.
> 
> -- 
> Michael Ash
> Rogue Amoeba Software

0
Erik
11/27/2005 7:58:00 PM
"Erik" <groups@customvisualdesigns.com> writes:
> Essentially, I was going to test everything by trying to tie in the
> objc_lookUpClass function.  As I understand it, this requires including
> the objc-runtime.h file (which in turn calls the objc-class.h file).
> So, basically that's what I did.  When I tried to compile, I got this:
> 
> /usr/include/objc/objc-class.h:171: error: syntax error at '@' token
> /usr/include/objc/objc-class.h:171: error: parse error before
> "Protocol"
> /usr/include/objc/objc-class.h:176: error: parse error before
> "Protocol"
> 
> The process stops every time at the "@class Protocol;" on line 171, and
> then the Protocol list struct that comes immediately thereafter.

In Panther, objc/objc-class.h can only be included in Objective-C 
or Objective-C++ files, because `@protocol` is only recognizable as 
Objective-C syntax. In Tiger, objc-class.h was changed to allow 
it to be included in C and C++ files as well. If you don't mind 
hacking your system header files, you could make the same change 
on Panther:

#ifdef __OBJC__
@class Protocol;
#else
typedef struct objc_object Protocol;
#endif


-- 
Greg Parker     gparker@apple.com     Runtime Wrangler

0
Greg
11/28/2005 10:42:51 PM
Greg,

Thank you for the tip!

Erik

Greg Parker wrote:
> "Erik" <groups@customvisualdesigns.com> writes:
> > Essentially, I was going to test everything by trying to tie in the
> > objc_lookUpClass function.  As I understand it, this requires including
> > the objc-runtime.h file (which in turn calls the objc-class.h file).
> > So, basically that's what I did.  When I tried to compile, I got this:
> >
> > /usr/include/objc/objc-class.h:171: error: syntax error at '@' token
> > /usr/include/objc/objc-class.h:171: error: parse error before
> > "Protocol"
> > /usr/include/objc/objc-class.h:176: error: parse error before
> > "Protocol"
> >
> > The process stops every time at the "@class Protocol;" on line 171, and
> > then the Protocol list struct that comes immediately thereafter.
>
> In Panther, objc/objc-class.h can only be included in Objective-C
> or Objective-C++ files, because `@protocol` is only recognizable as
> Objective-C syntax. In Tiger, objc-class.h was changed to allow
> it to be included in C and C++ files as well. If you don't mind
> hacking your system header files, you could make the same change
> on Panther:
>
> #ifdef __OBJC__
> @class Protocol;
> #else
> typedef struct objc_object Protocol;
> #endif
> 
> 
> -- 
> Greg Parker     gparker@apple.com     Runtime Wrangler

0
Erik
11/30/2005 6:05:24 AM
Reply: