now ,I have a framework named "MyFramework.framework" which include a window.nib, and I write a example to invoke it in terminal.
code:
//<MyFramework/myUI.h>
#ifndef Frmwork_myUI_h
#define Frmwork_myUI_h
#ifdef __cplusplus
extern "C"{
#endif
void ShowDialog();
#ifdef __cplusplus
}
#endif
#endif
//test.mm
#include <MyFramework/myUI.h>
#include <Foundation/NSRunLoop.h>
int main(int argc, char *argv[])
{
ShowDialog() ;
while (!isTransmitCompleted)
{
[[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
}
return 0;
}
//build test.mm
g++ -c test.mm -o test.o
g++ test.o -o test -lpthread -framework Cocoa -framework AppKit -framework CoreData -framework Foundation -framework MyFramework
//run
$./test
the Dialog can appear, but it seems be blocked ,it has no focus , I can not input anything, I can do nothing ,what is wrong?
now , I got the solution.
In OS X 10.6 ,I write a npapi plugin for Safari, In this plugin I invoke an framework which shows a Modal Window to get password. after close this modal window ,the Safari seems to block.
In my framework , I show this modal window by runModalForWindow function ,when I change to runModalSession , everything works perfectly. I don`t know why but it really works for me .
Related
The codes are like this:
#import <Foundation/Foundation.h>
#import <Cocoa/Cocoa.h>
int main(int argc, const char * argv[])
{
#autoreleasepool {
// insert code here...
NSLog(#"Hello, World!");
}
NSAlert *alert = [[NSAlert alloc] init];
[alert setMessageText:#"Hi there."];
[alert runModal];
return 0;
}
What I want is: when called from command line, this program pops up an alert box, when I close the alertbox. The program exits.
But when building, it complains like this:
Ld /Users/hanfei/Library/Developer/Xcode/DerivedData/KeyCatcher-hijnrqhwiafuxtdjmdubtsijyhwh/Build/Products/Debug/KeyCatcher normal x86_64
cd /Users/hanfei/Desktop/KeyCatcher
setenv MACOSX_DEPLOYMENT_TARGET 10.9
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang -arch x86_64 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.9.sdk -L/Users/hanfei/Library/Developer/Xcode/DerivedData/KeyCatcher-hijnrqhwiafuxtdjmdubtsijyhwh/Build/Products/Debug -F/Users/hanfei/Library/Developer/Xcode/DerivedData/KeyCatcher-hijnrqhwiafuxtdjmdubtsijyhwh/Build/Products/Debug -filelist /Users/hanfei/Library/Developer/Xcode/DerivedData/KeyCatcher-hijnrqhwiafuxtdjmdubtsijyhwh/Build/Intermediates/KeyCatcher.build/Debug/KeyCatcher.build/Objects-normal/x86_64/KeyCatcher.LinkFileList -mmacosx-version-min=10.9 -fobjc-arc -fobjc-link-runtime -framework Foundation -Xlinker -dependency_info -Xlinker /Users/hanfei/Library/Developer/Xcode/DerivedData/KeyCatcher-hijnrqhwiafuxtdjmdubtsijyhwh/Build/Intermediates/KeyCatcher.build/Debug/KeyCatcher.build/Objects-normal/x86_64/KeyCatcher_dependency_info.dat -o /Users/hanfei/Library/Developer/Xcode/DerivedData/KeyCatcher-hijnrqhwiafuxtdjmdubtsijyhwh/Build/Products/Debug/KeyCatcher
Undefined symbols for architecture x86_64:
"_OBJC_CLASS_$_NSAlert", referenced from:
objc-class-ref in main.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
When I choose the template for new project, I select command line tool instead of CoCoa Application as I just need CoCoa to display an alertbox. Does anyone have ideas about this..
That's because NSAlert is not #imported.
AppKit.h is not included by default when you create a command line tool , as you can see in the link, AppKit imports NSAlert.h.
EDIT:
First, to compile you need to add the Cocoa framework in your project.
Second, all the code should be enclosed in the #autoreleasepool section
#autoreleasepool {
// insert code here...
NSLog(#"Hello, World!");
NSAlert *alert = [[NSAlert alloc] init];
[alert setMessageText:#"Hi there."];
[alert runModal];
}
Your code will compile and run, but I think you'll have some other runtime errors.
I got the same error in C++ project that was using a NSAlert, this worked for me:
1) Adding
#include <Cocoa/Cocoa.h>
2) Adding Cocoa Framework in project->Buld Phases->Link Binary With Libraries.
3) Setting "Type" of all my .cpp files to "Objective-C++ Source" in the most right column in xCode.
you need to add this before main function
#import <AppKit/AppKit.h>
You need to import AppKit as mentioned by others and – as important as the framework – you need a run loop. So insert before the runModal line
[NSApplication sharedApplication];
to launch the "application" and the run loop
Basically, I followed the instructions here: http://wiki.gnustep.org/index.php/GNUstep_under_Ubuntu_Linux
With the extra step of building the gui and back.
If I build and run a non-gui program, all works well. Only when I add something that uses the gui, like the following:
// Created by Tobias Lensing on 2/22/13.
#import <Foundation/Foundation.h>
#import <AppKit/AppKit.h>
#import <dispatch/dispatch.h>
int main(int argc, const char * argv[])
{
#autoreleasepool {
int multiplier = 7;
int (^myBlock)(int) = ^(int num) {
return num * multiplier;
};
NSLog(#"%d", myBlock(3));
dispatch_queue_t queue = dispatch_queue_create(NULL, NULL);
dispatch_sync(queue, ^{
printf("Hello, world from a dispatch queue!\n");
});
// dispatch_release(queue); // ARC takes care of this
}
#autoreleasepool {
[NSApplication sharedApplication];
NSRunAlertPanel(#"Test", #"Wow it works!", #"OK", nil, nil);
}
return 0;
}
I compile this with the following:
clang `gnustep-config --objc-flags` `gnustep-config --objc-libs` -fobjc-arc -fobjc-runtime=gnustep -fblocks -lobjc -ldispatch -lgnustep-gui test.m
It compiles and links with no errors.
When I run it, however, it spits out the following ugly-gram:
Hello, world from a dispatch queue!
Objective-C ABI Error: Loading modules from incompatible ABI's while loading .GSBackend.m
a.out: /home/lloyd/projects/ThirdParty/BuildGnuStep/libobjc2/loader.c:53: void __objc_exec_class(struct objc_module_abi_8 *): Assertion `objc_check_abi_verion(module)' failed.
Aborted (core dumped)
I have assured myself that there is no other version of libobjc (this is on a virtual machine so I can go back redo my steps).
Commenting out the following:
// [NSApplication sharedApplication];
// NSRunAlertPanel(#"Test", #"Wow it works!", #"OK", nil, nil);
and everything compiles and runs, aside from the GUI obviously.
How can I have two ABI's when I build everything from scratch? Do I need to configure the GUI differently? I've been puzzling over this for a couple of weeks.
Sorry, too long for a comment:
Well I am not sure of you exact problem but you have 3 ABI'a to consider rather than just the normal 2 (gnustep, fragile, not-fragile)... I am not an absolute expert on the area, but I believe you can run gnustep against the newer apple non-fragile ABI... so it is possible that isn't the ABI you have, but it is the one that gets selected with: gnustep-config --objc-libs, you could try omitting that...
I always used gnustep-make, but I haven't done much gnustep for a long time, and don't know if that is still preferred.
I did find an interesting thread: http://comments.gmane.org/gmane.comp.lib.gnustep.general/38698
Okay, after much messing around I discovered that, surprise, I was building everything wrong.
I would go into the long, deep, painful process, but this website actually has a nice set up, scripts, and everything.
Sadly I didn't find this website before asking my question. Now I have Objective C, ARC, blocks and GNUstep!
Update: This was fixed in iOS 6.1 DP3 SDK.
I've tracked down a use-after-deallocated crash when building with ARC using the default release build configuration (debug seems to work fine). The problem occurs when creating an object inside an if-scope with a non-constant condition, assigning it to a variable from outside the scope and then only referencing the variable using Objective-C array or dictionary literals.
Here is the smallest reproducible case I've managed to find:
void test(BOOL arg)
{
id obj = nil;
if (arg) {
obj = [NSObject new];
}
// obj already deallocated here
#[obj];
// but using NSArray works
//[NSArray arrayWithObject:obj];
// #[obj] works if obj is referenced i.e. by NSLog print out
//NSLog(#"%#", obj);
}
int main(int argc, const char * argv[])
{
#autoreleasepool {
test(YES);
}
return 0;
}
When I build and run this with zombie objects enabled I get this error message:
-[NSObject retain]: message sent to deallocated instance 0x100109100
As I commented in the code it works fine if obj is referenced in some other way, like with NSLog or using NSArray instead. Have I misunderstood how objects are released with ARC and scopes or is this a optimization bug in LLVM or Clang?
I'm using Xcode 4.5.2 with clang version 4.1 (tags/Apple/clang-421.11.66) (based on LLVM 3.1svn). I can reproduce it when building for x86 64 bit for iOS simulator and Mac OS X and I'm quite sure the same problem occurs when building for ARM as the issue was first found when running release build on an iPhone.
I have filed and bug report to Apple and created an open radar report.
What, if anything, am I missing?
Update, did some more experiments:
As Gabro pointed out the compiler translates #[] to a [NSArray arrayWithObjects:count:] statement so I did some tests:
// works
id a[] = {obj};
[NSArray arrayWithObjects:a count:1];
// does not work
const id *b = (id[]){obj};
[NSArray arrayWithObjects:b count:1];
// does not work
[NSArray arrayWithObjects:(id[]){obj} count:1];
So my guess is that this happens when combining ARC and anonymous C arrays.
You're not missing anything. It's a compiler bug.
I just tested the following code both building for OSX (x86 64) and iOS Simulator and I cannot reproduce the bug
void test(BOOL arg) {
id obj = nil;
if (arg) {
obj = [NSObject new];
}
#[obj];
NSLog(#"Hi there");
}
int main(int argc, const char * argv[]) {
#autoreleasepool {
test(YES);
}
return 0;
}
The above code simply prints Hi there in the console and returns.
My configuration is the same of yours: XCode 4.5.2 and Apple clang version 4.1 (tags/Apple/clang-421.11.66) (based on LLVM 3.1svn) as a compiler.
EDIT
I also tried to compile from command line (after adding #include <Foundation/Foundation.h>
at the beginning of the above example) using
clang -fobjc-arc -framework Foundation main.m
And the result was again
2012-12-03 12:47:45.647 a.out[39421:707] Hi there
EDIT 2
As pointed out in the comments it is possible to reproduce the bug increasing the optimization level over -O0. Summarizing:
clang -O0 -fobjc-arc -framework Foundation main.m
the program works as expected
clang -O1 -fobjc-arc -framework Foundation main.m
the bug presented in the question shows up. This is true with any optimization level over -O0
It's definitely a bug in the compiler.
ok i have this program here:
int main(int argc, const char * argv[])
{
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
NSLog (#"Hello world!");
[pool drain];
return 0;
}
the problem is when i compile it with the command
"gcc -framework Foundation prog1.m -o prog1"
i get this:
"gcc: error trying to exec 'cclobj' : execvp: No such file or Directory"
do i need to install any packages??
"
Its not the only way but GNUStep worked for me. For a good writeup on setting it up look here.
Note: Your exact error is listed about halfway down that page. Your missing package seems to be 'gobjc'.
You need to install "gobjc"
Example
gcc -x objective-c -o
check this link Compiling Objective-C using the gcc
http://webcache.googleusercontent.com/search?q=cache:iIgkFc-JoRYJ:https://www.cs.indiana.edu/classes/c304/ObjCompile.html+http://www.it.uc3m.es/mibanez/lao/lab1/tutorial3/ObjCompile.html&cd=1&hl=en&ct=clnk&client=safari
I know how to compile the objective c program using gnustep version of mingw.
But I don't like their shell and I want to use the standard mingw gcc compiler.
I put this gcc bin directory in environment path of course, open command prompt in my helloworld.m directory
#import <Foundation/Foundation.h>
int main (int argc, const char * argv[])
{
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
NSLog (#"Hello World!");
[pool drain];
return 0;
}
and type
gcc -o hello hello.m -I /GNUstep/System/Library/Headers -L /GNUstep/System/Library/Libraries -lobjc -lgnustep-base -fconstant-string-class=NSConstantString
but it doesn't work because it cannot find foundation/foundation.h
How to fix this and if possible avoid hardcoding in hello source code ?
Have a look here at the end of the post the blogger says to write:
gcc `gnustep-config --objc-flags` -o hello2 hello2.m -L /GNUstep/System/Library/Libraries -lobjc -lgnustep-base
It seems like you always have to pass through GNUStep
I had the same problem.Modifying command line like below solved my problem.
gcc -I"c:/GNUstep/GNUstep/System/Library/Headers" -L "c:/GNUstep/GNUstep/System/Library/Libraries" -o hello hello.m -lobjc -lgnustep-base -fconstant-string-class=NSConstantString