I am trying to compile my first Objective-C program. It is just the simple "Programming is fun!" code:
#import <Foundation/Foundation.h>
int main (int argc, const char * argv[])
{
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
NSLog (#"Programming is fun!");
[pool drain];
return 0;
}
I downloaded the gnustep-msys-system-0.30.0-setup.exe and gnustep-core-0.34.0-setup.exe and installed them in that order. I copied the file named prg1.m (which contain the previous code) to the /GNUstep/msys/1.0/home/username folder. I opened the GNUstep shell and proceeded to issue the following command:
gcc -o prg1 prg1.m -I /GNUstep/System/Library/Headers -L /GNUstep/System/Library/Libraries -lobjc -lgnustep-base -fconstant-string-class=NSConstantString
I get the following output:
In file included from C:/GNUstep/GNUstep/System/Library/Headers/GNUstepBase/GSCo
nfig.h:281:0,
from C:/GNUstep/GNUstep/System/Library/Headers/GNUstepBase/GSVe
rsionMacros.h:219,
from C:/GNUstep/GNUstep/System/Library/Headers/Foundation/Found
ation.h:30,
from prg1.m:1:
c:\mingw\include\w32api.h:27:2: warning: #warning WARNING - The w32api.h header
file is deprecated and will be removed. [-Wcpp]
#warning WARNING - The w32api.h header file is deprecated and will be removed.
^
In file included from C:/GNUstep/GNUstep/System/Library/Headers/Foundation/NSPor
tMessage.h:30:0,
from C:/GNUstep/GNUstep/System/Library/Headers/Foundation/Found
ation.h:99,
from prg1.m:1:
C:/GNUstep/GNUstep/System/Library/Headers/Foundation/NSPort.h:210:3: error: unkn
own type name 'WSAEVENT'
WSAEVENT eventListener;
^
Anyone know why I am getting this error at the end? I have been googling it for a couple of hours without much luck. Any help would be greatly appreciated. Thanks in advance.
The issue you have seems to be in the foundation/foundation.h library you downloaded. The real question here is it seems you are using a PC as you downloaded a .exe thus I wonder, why are you programing in Objective-C? The only platform that still uses Objective-C is the iOS/Apple platform which you really can not effectively code for with out an Apple computer. If you just want to learn Objective-C because you plan to get into iOS soon then I understand but if you do not plan to do this then there is no reason to learn Objective-C, you are better off learning Java, C# or C++.
The more specific answer to your question is that WSAEVENT is a signal used in windows threads. Chances are somehow your system is not finding the support for it correctly it may be because the w32api.h was removed which had the reference to where the WSAEVENT was located.
Related
Trying to automatically view a computer in Apple Remote Desktop via Scripting Bridge in Objective-C with this:
#try {
SBApplication *RD = [SBApplication applicationWithBundleIdentifier:#"com.apple.RemoteDesktop"];
// (code to check for ARD running and installed omitted here)
[RD activate]; // works just fine
RemoteDesktopComputer *computer = [[[RD classForScriptingClass:#"computer"] alloc] initWithProperties:
[NSDictionary dictionaryWithObjectsAndKeys:
ipAddress,#"InternetAddress", // looked up from header
nil
]
];
// attempt to add it to a container first:
[(SBElementArray*)[(RemoteDesktopApplication*)RD computers] addObject:computer];
// this is what raises the exception:
[computer observeZooming:Nil];
}
#catch (NSException *e) {
NSLog(#"Exception: %#", [e description]);
}
Running this yields the following exception in the log:
Exception: *** -[SBProxyByClass observeZooming:]: object has not been added to a container yet; selector not recognized [self = 0x6050004819b3]
I've done as much research as there is available on this subject and have learned that SB isn't the easiest to deal with because of how it's wired under the hood, but any experts or veterans of native Scripting Bridge (no third party frameworks or languages other than obj-c, please) is much appreciated.
All prerequisites like linking to the ScriptingBridge.framework and importing Remote Desktop.h are performed - the typecasts are to avoid what appear to be unavoidable link-time errors when building...
Edit 1: Reading the documentation on SBObject (parent of RemoteDesktopComputer) says that it's a reference rather than an actual instance, which you can fetch by calling SBObject's get method (returns id). So I tried running this as well but unfortunately received the same results:
[[computer get] observeZooming:Nil];
Here's the documentation on SBObject: https://developer.apple.com/library/mac/documentation/cocoa/Reference/SBObject_Class/SBObject/SBObject.html#//apple_ref/occ/instm/SBObject/get
Still trying...
(FWIW, I already had the following How To written up, so I'm leaving it here for future reference.)
How to use AppleScript-ObjC in place of Scripting Bridge
Scripting Bridge is, at best, an 80/20/80 "solution" (i.e. 80% of the time it works, 20% of the time it fails, and 80% of the time you've no idea why). There's little point trying to argue with SB when it breaks on stuff that works perfectly well in AppleScript - the Apple engineers responsible designed it that way on purpose and simply refuse to accept they broke spec [1] and screwed up. As a result, the AppleScript language, for all its other deficiencies, remains the only supported solution that is guaranteed to speak Apple events correctly [2].
Fortunately, since OS X 10.6 there has been another option available: use ObjC for all your general programming stuff, and only call into AppleScript via the AppleScript-ObjC bridge for the IPC stuff.
From the POV of your ObjC code, your AppleScript-based ASOC 'classes' are more or less indistinguishable from regular ObjC classes. It requires a bit of fiddling to set up, and you'll pay a bit of a toll when crossing the bridge, but given the crippled, unreliable nature of the alternatives, it's the least horrid of the supported options for anything non-trivial.
Assuming you've already got an existing ObjC-based project, here's how to add an ASOC-based class to it:
In Targets > APPNAME > Build Phases > Link Binary With Libraries, add AppleScriptObjC.framework.
In Supporting Files > main.m, add the import and load lines as shown:
#import <Cocoa/Cocoa.h>
#import <AppleScriptObjC/AppleScriptObjC.h>
int main(int argc, const char * argv[]) {
[[NSBundle mainBundle] loadAppleScriptObjectiveCScripts];
return NSApplicationMain(argc, argv);
}
To define an ASOC-based class named MyStuff that's callable from ObjC, create a MyStuff.h interface file that declares its public methods:
// MyStuff.h
#import <Cocoa/Cocoa.h>
#interface MyStuff : NSObject
// (note: C primitives are only automatically bridged when calling from AS into ObjC;
// AS-based methods with boolean/integer/real parameters or results use NSNumber*)
-(NSNumber *)square:(NSNumber *)aNumber;
#end
along with a MyStuff.applescript file containing its implementation:
-- MyStuff.applescript
script MyStuff
property parent : class "NSObject"
on square_(aNumber)
return aNumber ^ 2
end square_
end script
Because the MyStuff class doesn't have an ObjC implementation, the linker can't link your ObjC code to it at build-time. Instead, use NSClassFromString() to look up the class object at run-time:
#import "MyClass.h"
...
MyStuff *stuff = [[NSClassFromString(#"MyStuff") alloc] init];
Otherwise it's pretty much indistinguishable from a native ObjC class in normal use:
NSNumber *result = [stuff square: #3];
NSLog(#"Result: %#", result);
HTH
--
[1] Apple management broke up the original AppleScript team shortly after its initial release, causing its designers to quit in response, so a lot of knowledge of precisely how this stuff should work was lost. In particular, a full, formal specification was never produced for application developers to follow when designing their scripting support, so all they could do was use personal judgement and best guesses, then test against AppleScript to check it worked as hoped. Thus, AppleScript's own Apple event bridge is the de facto specification that every single scriptable app has been implemented against in the last twenty years, so the only way that other AE bridges can ever work correctly is if they mimic AS's own bridge down to every last query and quirk - a lesson, unfortunately, that the current AS team have repeatedly failed to understand [2].
[2] JavaScript for Automation's Apple event supported is equally crappy and busted, incidentally.
Scripting Bridge is a defective, obfuscated mess, so when an application command fails to work you've no idea if the problem is SB being defective or the application itself being buggy or simply requiring you to phrase it in a different way.
Therefore, the first step is to write a test script in AS to see it works there. If it does, it's SB that's crap; if not, try fiddling with your AS code (e.g. try phrasing the reference for the at parameter in different ways, or omitting it entirely) till it does.
You should also ask on Apple's AppleScript Users and ARD mailing lists and anywhere else that ARD scripters are likely to hang out, as most apps' scripting documentation is grossly inadequate, so a lot of knowledge of how to do things is word of mouth. (The guy you really want to talk to is John C Welch, aka #bynkii, as he's the guru of ARD scripting.)
Is it possible to generate a C source file (.c) from an Objective-C source file (.m), using, maybe, GCC or Clang (or another tool)?
No, but you may be interested in the C++ rewriter. Given an objective-C file, let's say:
#import <stdio.h>
int main() {
void (^blk)(void) = ^{
printf("hi");
};
blk();
return 0;
}
You can get a C++ version with
clang -rewrite-objc main.c
which is great to see how objective-C is implemented. Most of the file will be just C.
Some of the resulting expressions are dense. You'll need patience, C knowledge, and the Objective-C Runtime Reference. http://cdecl.org/ helps with small pieces.
I'm learning objc and Xcode from a handy free ebook called How To Become and Xcoder, which is quite handy. Except it was written in 2007 with Xcode 3 and its samples are all from that version unfortunately I have OSX Lion and thus Xcode 4. So to the grit of my question. They provide a sample block of code as seen here:
//start
#import <Foundation/Foundation.h
int main (int argc, const char * argv[])
{
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
NSLog(#"Hello, World!");
[pool drain];
return 0;
}
//end
So my problems are that I get over 20 errors and Xcode doesn't recognize the NSAutoreleasePool or NSLog commands.
Does anybody know why this won't work? I already added the Foundation framework.
The I've already realized that the printf command works better than the NSLog command (which to my knowledge is more so used for error reporting) so yeah any help would be nice.
If NSLog isn't being recognised, this isn't a problem to do with Xcode 3 versus Xcode 4. Your code isn't including the most basic Objective-C runtime code. I would assume that it's being compiled as C not Objective-C.
You say that you had to add the Foundation framework - this indicates that you didn't start your project using an Objective-C-based template. When you select New Project..., which template did you pick? Any of the iOS application templates should work, and most of the Mac OS X application templates should work. If you chose to build a command line tool, you should pick Foundation as the type.
Edit: Also, I should add that the syntax for autorelease pools has changed in the latest version of Xcode, as ARC is used by default. You can either switch ARC off, or read up on it to see what the differences are. Chances are you'll find it easier with ARC as there is much less memory management for you to worry about, but you will have to bear it in mind if you are following a book that doesn't account for it.
The Foundation is located on the screen where you need to give name to your project. As the default value it is set to C, in your case you need to click on the drop down menu and choose Foundation instead.
Good luck.
I'm running in to some strange errors when dabbling in some socket programming using Xcode 4. I get the error that addrinfo is undeclared, despite me simply copying the code from another project that did work (when using Xcode 3). The project is mainly in Objective-C, but I've tested creating another framework with plain C, and the error still remains.
I have the following frameworks included:
ApplicationServices.framework
Cocoa.framework
AppKit.framework
Foundation.framework
No added linker flags either.
However, other functions such as getaddrinfo (that uses addrinfo itself!) exists. Any ideas?
This issue wasn't IDE-related, it was a language issue. How structs are treated is apparently different in C (and thus Objective-c) and C++ (which the previous projects were=. So I changed the line
addrinfo hints;
To:
struct addrinfo hints;
Have you got the correct imports?
#import <netinet/in.h>
#import <sys/socket.h>
A quick grep shows that struct addrinfo is declared in <netdb.h>. Try explicitly including that. (Your Xcode 3 project may have included that, or some other header that includes it, in its prefix file.)
I'm trying to compile the following Objective-C program on Ubuntu Hardy, but for some reasons, I'm getting warnings.
#import <Foundation/Foundation.h>
int main (int argc, char *argv[])
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
NSLog (#"Hello");
[pool drain];
return 0;
}
Output of the compiler:
$ gcc `gnustep-config --objc-flags` -lgnustep-base objc.m
This is gnustep-make 2.0.2. Type 'make print-gnustep-make-help' for help.
Making all for tool LogTest...
Compiling file objc.m ...
objc.m: In function ‘main’:
objc.m:6: warning: ‘NSAutoreleasePool’ may not respond to ‘-drain’
objc.m:6: warning: (Messages without a matching method signature
objc.m:6: warning: will be assumed to return ‘id’ and accept
objc.m:6: warning: ‘...’ as arguments.)
Linking tool LogTest ...
Here's the result of the execution:
$ ./a.out
2009-06-28 21:38:00.063 a.out[13341] Hello
Aborted
I've done:
apt-get install build-essential gnustep gobjc gnustep-make libgnustep-base-dev
How do I fix this problem?
First, the simple answer: use -release instead. I believe -drain was added in 10.4 as an alias for -release, and in 10.5 it gained GC-specific behavior of its own. This allows code to use it in 10.5 and still work under 10.4. GNUstep probably doesn't yet have the new functionality.
Obviously you're trying out some boilerplate Objective-C code on Ubuntu, but it causes me to wonder what you're hoping to accomplish in the long term. Don't let me deter you if it's just out of curiosity or for the challenge of it. However, if you're planning to use GNUstep to develop Objective-C for serious programming, I would advise against it, for several reasons.
Objective-C is an interesting programming language with a number of powerful features, but not significantly more so (by itself) than other object-oriented languages. Objective-C really becomes compelling when you pair it with the cool features in Cocoa and other related frameworks. Apple (primarily) drives those frameworks, and only for Mac/iPhone.
Apple generally has the best tools and user experience for Objective-C development. They're also investing heavily in development of LLVM and Clang as a replacement for gcc. This will (an already does) make possible some very cool things that gcc wasn't designed for.
GNUstep is an admirable project, but since it depends on volunteers and reverse-engineering new features added by Apple, it always lags behind the state-of-the-art. The new shiny Objective-C features will always start with Apple and (usually) eventually trickle down.
Building cross-platform apps could be done in Objective-C, but other languages are much better suited for the task. (I'm not so much of a fanboy as to suggest that Objective-C is the best solution for every problem. Use the best tool you have at hand.)
I'm not saying using languages on something other than their "native platform" is bad. I'm just suggesting that if that's what you're going to do, you should be aware of the potential problems and be sure you're convinced that the pros outweigh the cons.
Sounds like the class library is out of date in GNUStep, at least in the version you're using -- [NSAutoreleasePool drain] was added in OS X 10.4 IIRC. I don't know anything about GNUStep though, so I don't know if newer libraries are available.
You can work around the problem by replacing 'drain' with 'release'. They do basically the same thing; the 'drain' method was added for use in a garbage-collected app, because 'release' becomes a no-op in that environment.
In my app main loop using GNUStep:
int main(int argc, const char *argv[])
{
NSAutoreleasePool *pool;
AppController *delegate;
pool = [[NSAutoreleasePool alloc] init];
// ...
[pool release];
return NSApplicationMain (argc, argv);
}