Writing an ObcJ function/calling it from C++
Essentially, that's what I'd like to do. The function will be simple, it just needs to make a simple dialog box with one button (I still have to learn how to do this...). I already know how to do this with the Windows API, just not Cocoa because I never directly use it myself. I'd like to be able to call this function from C++ code too, although I know ObjC structures it's functions differently.
What if I wrote the ObjC function, and then made a #define func(args) type layer for the function, would that work?
(Perhaps this is a stupid question, but ObjC is so different from C and C++ it seems like they'd never work together. Thanks!)
What if I wrote the ObjC function, and then made a #define func(args) type layer for the function, would that work?
(Perhaps this is a stupid question, but ObjC is so different from C and C++ it seems like they'd never work together. Thanks!)
Jones Wrote:(Perhaps this is a stupid question, but ObjC is so different from C and C++ it seems like they'd never work together. Thanks!)
Uh, actually, they do work together. Quite well, actually, and it's something I do a lot. If you're calling C/C++ code from another file, you can just call it (after including the header file or declaring it somehow in your Obj-C source file). Calling Obj-C code from C/C++ is a little trickier but it's doable. Poke around Apple's Developer website for sample code and documentation that talks about mixing Obj-C and C/C++.
The brains and fingers behind Malarkey Software (plus caretaker of the world's two brattiest felines).
If I may suggest, since you don't have much experience with Cocoa, why not just make a few programs out of nothing *but* Cocoa to really get your feet wet with it. That will make integration with other languages much easier to understand. Cocoa all by itself kicks major amounts of bootay. No, really, it does. Give it a try!
you could just use a simple carbon function... lemme find it...
oh yes, here it is.
shouldn't be too hard to adapt it for your purposes. No use in creating a C/C++ wrapper for objc, when you can just use the native functions.
oh yes, here it is.
Code:
#ifdef WIN32
#include <windows.h>
#elif defined __APPLE__
#include <Carbon/Carbon.h>
#endif
#include <cstdarg>
#include <iostream>
#include <sstream>
void ErrorMessage(const std::string &message);
void ErrorMessage(const std::string &message)
{
#ifdef WIN32
MessageBox(NULL, message.c_str(), "Error", MB_ICONERROR | MB_OK);
#elif defined __APPLE__
Str255 msg;
c2pstrcpy(msg, message.c_str());
StandardAlert(kAlertStopAlert, "\pError",
(ConstStr255Param)msg, NULL, NULL);
#else
std::cerr << "Error: " << error_text << std::endl;
#endif
}shouldn't be too hard to adapt it for your purposes. No use in creating a C/C++ wrapper for objc, when you can just use the native functions.
It's not magic, it's Ruby.
Disaster strikes:
I ashamed to say that I can't even get this dialog to display correctly.
One simple call of:
Causes an application crash with multiple errors, like:
But many more than just three... those look like Cocoa errors. Perhaps Carbon and Cocoa are duking it out? I was under the impression that GLUT used Carbon.
Thanks!
I ashamed to say that I can't even get this dialog to display correctly.
One simple call of:
Code:
StandardAlert( kAlertCautionAlert,
(const unsigned char*)title,
(const unsigned char*)message, NULL, NULL);Causes an application crash with multiple errors, like:
Quote:2006-11-18 11:55:46.154 OpenGL[16185] *** _NSAutoreleaseNoPool(): Object 0x3711b0 of class NSCarbonWindowContentView autoreleased with no pool in place - just leaking
2006-11-18 11:55:46.177 OpenGL[16185] *** _NSAutoreleaseNoPool(): Object 0xa370d7d8 of class NSCFString autoreleased with no pool in place - just leaking
2006-11-18 11:55:46.208 OpenGL[16185] *** _NSAutoreleaseNoPool(): Object 0x374100 of class NSCFDictionary autoreleased with no pool in place - just leaking
But many more than just three... those look like Cocoa errors. Perhaps Carbon and Cocoa are duking it out? I was under the impression that GLUT used Carbon.
Thanks!
GLUT is based on Cocoa on OS X -- because Cocoa kicks major bootay. Cocoa and Carbon work together just fine. It looks like you did some Cocoa stuff without first creating an NSAutoReleasePool.
[edit] You could do that like this:
NSAutoreleasePool *myAutoReleasePool = [[NSAutoreleasePool alloc] init];
// do Cocoa stuff
[myAutoReleasePool release];
[/edit]
[edit] You could do that like this:
NSAutoreleasePool *myAutoReleasePool = [[NSAutoreleasePool alloc] init];
// do Cocoa stuff
[myAutoReleasePool release];
[/edit]
*Becomes baffled by Cocoa code.*
I think I've come up with another solution involving using a seperate executable. It sounds weird, but it's mainly for debugging purposes...
That code, BTW, would be much easier to use in an SDL app. I use GLUT apps when designing components and SDL when snapping them together for demonstrations, and later, games. It's a bit of a messy system, but it works for me.
I think I've come up with another solution involving using a seperate executable. It sounds weird, but it's mainly for debugging purposes...
That code, BTW, would be much easier to use in an SDL app. I use GLUT apps when designing components and SDL when snapping them together for demonstrations, and later, games. It's a bit of a messy system, but it works for me.
that code I gave you before will work in an sdl app. I'm not sure why it doesn't in your glut app...try it in SDL before giving up on it. That error will haunt you if you use cocoa, anyway.
It's not magic, it's Ruby.
Jones Wrote:*Becomes baffled by Cocoa code.*An NSAutoReleasePool is a really cool way to manage memory but it isn't an intuitive technique to grasp on first glance. It's essentially just a list of objects which you would like to have released when you release the pool. As you may know, Cocoa objects have the notion of a retain count. A retain count of zero means that the runtime should destroy the object. To set the object's retain count, you can retain, release, and autorelease. In short (really short), retain means add one to the retain count, release means subtract one from the retain count, and autorelease means subtract one from the retain count later -- typically at the end of the application's current execution cycle, when the release message is sent to the autorelease pool you created. Autorelease is handy because often times an object will initialize itself but has no interest in itself, but needs to make sure it stays around long enough for the object that called it in the first place to do something with it. Also, many objects are used in a transient fashion, such as an NSString used as an argument to another string for a moment. Calling release on objects like that all the time becomes redundant, so for convenience, many classes return autoreleased objects. If there isn't a list of autoreleases (an autoReleasePool) then there is no way to tell the runtime to release them and they become memory leaks.
ok, try this:
1. change your main function's file's extension to '.mm' from '.cpp', '.cxx', '.cc', '.C', etc.
2. add "#import <Foundation/Foundation.h>" to the beginning of your file.
3. add "NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];" to the first line of the main function.
4. add "[pool release];" to the last line before your return in the main function.
5. add the foundation framework to the project, if you're using xcode.
6. compile! it might work. Not sure why this should pop up in the first place; doesn't GLUT sue cocoa?
1. change your main function's file's extension to '.mm' from '.cpp', '.cxx', '.cc', '.C', etc.
2. add "#import <Foundation/Foundation.h>" to the beginning of your file.
3. add "NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];" to the first line of the main function.
4. add "[pool release];" to the last line before your return in the main function.
5. add the foundation framework to the project, if you're using xcode.
6. compile! it might work. Not sure why this should pop up in the first place; doesn't GLUT sue cocoa?
It's not magic, it's Ruby.
Nayr Wrote:ok, try this:
1. change your main function's file's extension to '.mm' from '.cpp', '.cxx', '.cc', '.C', etc.
2. add "#import <Foundation/Foundation.h>" to the beginning of your file.
3. add "NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];" to the first line of the main function.
4. add "[pool release];" to the last line before your return in the main function.
5. add the foundation framework to the project, if you're using xcode.
6. compile! it might work. Not sure why this should pop up in the first place; doesn't GLUT sue cocoa?
Somehow that sounds like the kind of solution Microsoft might use. It's quick, but it might break in the future. No offense, of course.

Somehow telling xCode to compile a bunch of c++ dependent code as ObjC sounds like 2000 compiler errors.
it's actually objective-c++. It should work fine; it IS a hack, though, only good to hold you over till you find the way you're supposed to do it.
It's not magic, it's Ruby.
Write a header file like this:
Now write an implementation file for that header:
If you name that implementation file .c, you can write C code; if you name it .cc, .cpp, .cxx, etc. you can write C++ code; if you name it .m you can write ObjC code, if you name it .mm you can write ObjC++ code. You can include the header in files written in any of those languages, too.
This is the "old-fashioned" way of mixing C++ and ObjC, but it has the advantage that it keeps the code in the other language nice and isolated from the rest of your code.
Oh, and the NSAutoreleasePool messages are not the cause of your crashes; a fundamental lack of understanding of C vs. Pascal strings, combined with a cavalier attitude toward compiler errors and warnings, is the cause of your crashes.
Also, don't use StandardAlert; it's ancient, nasty, and deprecated. There are better ways of doing it (just say whether you want Cocoa or Carbon code).
And no, GLUT on Mac OS X does not use Carbon internally; it's implemented using Cocoa. You can download the source from Apple.
Code:
#ifndef MyHeaderName_h
#define MyHeaderName_h
#if defined(__cplusplus)
extern "C" {
#endif
extern void myCFunctionPrototype(int arg0, const char *arg1, double arg2orWhatever);
#if defined(__cplusplus)
}
#endif
#endifNow write an implementation file for that header:
Code:
#include "MyHeaderName.h"
void myCFunctionPrototype(int arg0, const char *arg1, double arg2orWhatever)
{
// your code goes here
}If you name that implementation file .c, you can write C code; if you name it .cc, .cpp, .cxx, etc. you can write C++ code; if you name it .m you can write ObjC code, if you name it .mm you can write ObjC++ code. You can include the header in files written in any of those languages, too.
This is the "old-fashioned" way of mixing C++ and ObjC, but it has the advantage that it keeps the code in the other language nice and isolated from the rest of your code.
Oh, and the NSAutoreleasePool messages are not the cause of your crashes; a fundamental lack of understanding of C vs. Pascal strings, combined with a cavalier attitude toward compiler errors and warnings, is the cause of your crashes.
Also, don't use StandardAlert; it's ancient, nasty, and deprecated. There are better ways of doing it (just say whether you want Cocoa or Carbon code).
And no, GLUT on Mac OS X does not use Carbon internally; it's implemented using Cocoa. You can download the source from Apple.
Jones Wrote:Somehow that sounds like the kind of solution Microsoft might use. It's quick, but it might break in the future. No offense, of course.
Somehow telling xCode to compile a bunch of c++ dependent code as ObjC sounds like 2000 compiler errors.
what on earth are you talking about, this is THE way to do it. Its a very clean and good solution.
Sir, e^iπ + 1 = 0, hence God exists; reply!
Possibly Related Threads...
| Thread: | Author | Replies: | Views: | Last Post | |
| Writing libraries vs writing apps. | Najdorf | 8 | 4,464 |
Nov 13, 2008 02:32 PM Last Post: backslash |
|
| Better way of calling a function in another class? | brush | 5 | 3,907 |
Jun 12, 2008 11:23 PM Last Post: AnotherJake |
|
| Problem drawing pictures after calling RunApplicationEventLoop | petr6534 | 5 | 4,179 |
Feb 8, 2005 06:58 PM Last Post: petr6534 |
|

