PDA

View Full Version : Using Cocoa elements through dylib in c++ app




tohihaho
Sep 17, 2008, 08:37 AM
Hi all!
I have such problem: I want to make a cocoa-made window with some functionality, that I can "call" from a c++-made application (even using wxWidgets).
I have managed to build a dynamic library, open it in the other application and run a function from it. That function starts a method that opens the cocoa window, but in the main application - there is no effect.
Please tell me what should I do so that in the c++-build application to run the cocoa-functionality.
Thanks in advance.

Toni



kainjow
Sep 17, 2008, 01:37 PM
You will need to be much more specific. Are you getting run time errors? Have you initialized the Cocoa frameworks properly with NSApplicationLoad()? Have you setup your autorelease pools properly?

tohihaho
Sep 18, 2008, 04:27 AM
Yes, I have set the autorelease pools properly, I don't get any errors.
As I was thinking about the problem I realize that I will need a way to somehow load a nib file or imitate it in some way. Can I have "cocoa elements" running independently from a nib file or specific cocoa application?

tohihaho
Sep 18, 2008, 05:46 AM
OK ... here is what I have:

@implementation CallerController

- (void) run
{
NSRunAlertPanel(@"bla", @"bla", @"bla", @"bla", nil);
[win1 orderFront:self];
}

@end

#include "symbols.h"
#include "CallerController.h"

void doIt()
{
NSAutoreleasePool *autoreleasepool = [[NSAutoreleasePool alloc] init];
printf("bla\n");
NSRunAlertPanel(@"bla", @"bla", @"bla", @"bla", nil);
CallerController * call = [CallerController alloc];
[call run];
[autoreleasepool release];
}

The second code I build in a dylib and use in other application like this:

int main(int argc, char *argv[])
{
char* lib_name = "../Probi/DynamicBase/build/Debug/Dynamic.dylib";
void* lib_handle = dlopen(lib_name, RTLD_NOW);

if (lib_handle)
{
printf("[%s] dlopen(\"%s\", RTLD_NOW): Successful\n", __FILE__, lib_name);
}
else
{
printf("[%s] Unable to open library: %s\n", __FILE__, dlerror());
exit(EXIT_FAILURE);
}

void (*doIt)(void) = dlsym(lib_handle, "_Z4doItv");
if (doIt)
{
printf("[%s] dlsym(lib_handle, \"doIt\"): Successful\n", __FILE__);
}
else
{
printf("[%s] Unable to get symbol: %s\n", __FILE__, dlerror());
}
doIt();
if (!dlclose(lib_handle))
{
printf("[%s] dlclose: Successful\n", __FILE__, lib_name);
}
else
{
printf("[%s] Unable to close library: %s\n", __FILE__, dlerror());
exit(EXIT_FAILURE);
}
return 0;
}


The result is:

[Session started at 2008-09-18 13:44:40 +0300.]
[/Users/tohihaho/wxWidgetsHelloWorld/main.m] dlopen("../Probi/DynamicBase/build/Debug/Dynamic.dylib", RTLD_NOW): Successful
[/Users/tohihaho/wxWidgetsHelloWorld/main.m] dlsym(lib_handle, "doIt"): Successful
bla
[/Users/tohihaho/wxWidgetsHelloWorld/main.m] dlclose: Successful

wxWidgetsHelloWorld has exited with status 0.

And no windows start.
win1 is an outlet that is connected to a window in a nib file.
Now I understand that I somehow should load the nib file, or make this whole thing work without it. What should I do?

kainjow
Sep 18, 2008, 10:37 AM
I'm pretty sure you need NSApplicationLoad() if you're not using NSApplicationRun() or calling [NSApplication sharedApplication] to initialize it because you need to load the frameworks and setup a run loop.

Second, nib files don't just load themselves. You have to load them specifically. There are several ways, the most common being NSBundle, NSWindowController, NSViewController or NSNib. But obviously you probably aren't inside a bundle, so you will somehow need to find the path of your nib. That's up to you to decide.

Third, never call only alloc on an object. Call alloc/init, or the designated initializer method. So it would look like:
CallerController * call = [[CallerController alloc] init];

tohihaho
Sep 23, 2008, 03:44 AM
Thanks for the help. I'll try to make it work now.

Edit: Calling NSApplicationLoad() worked. Thanks a lot :)