In my Windows application I have the ASSERT function, which evaluates
an expression and, once the expression evaluates to false, displays an
appropriate error message and aborts the program. This ASSERT function
sits in a separate library underneath the applicatin layer and
therefore known nothing about the latter. However it should somehow
know whether the application calling it is GUI or console in order to
know where to display the error message: either show MessageBox
('alert' in Mac terms) or write it to console. In Win32 I deduce the
application type by analysing the header of the executable which
corresponds to the current process of the application. If it is
console application, I write the message to console, if it is GUI a
display a Message Box.
I am wondering if it is possible to do the same in MAC?
You're porting a Windows app to Media Access Controllers? Oh, you mean
Mac.
> In my Windows application I have the ASSERT function, which evaluates
> an expression and, once the expression evaluates to false, displays an
> appropriate error message and aborts the program. This ASSERT function
> sits in a separate library underneath the applicatin layer and
> therefore known nothing about the latter. However it should somehow
> know whether the application calling it is GUI or console in order to
> know where to display the error message: either show MessageBox
> ('alert' in Mac terms) or write it to console. In Win32 I deduce the
> application type by analysing the header of the executable which
> corresponds to the current process of the application. If it is
> console application, I write the message to console, if it is GUI a
> display a Message Box.
There is no strict line between GUI and console programs on OS X, so this
may not be possible in all cases.
However, I imagine that you will get the right answer about 99% of the
time if you assume that an executable bundled inside a .app bundle
structure is GUI, and an executable outside of such a bundle is console.
--
Michael Ash
Rogue Amoeba Software
Thanks, it is something at least.
CFBundle or NSBundle can get you the path to the current executable.
Deciding whether that's the executable of a .app bundle should be
relatively easy. If you don't understand bundle structures, Apple has a
whole document about it:
Thanks, I have already done it with bundle API. Any comments?
char myPath[MAXPATHLEN+1];
unsigned int myPathLen = MAXPATHLEN;
_NSGetExecutablePath(myPath, &myPathLen);
CFStringRef myNameAsCFStr = CFStringCreateWithCString(NULL, myPath,
kCFStringEncodingMacRoman);
CFURLRef myNameUrl = CFURLCreateWithString(NULL, myNameAsCFStr, NULL);
UInt32 myPackageType, myPackageCreator;
bool myIsBundle = CFBundleGetPackageInfoInDirectory(myNameUrl,
&myPackageType, &myPackageCreator);
if (myIsBundle)
..//UI
else
//console
--Andei
Why are you using an unsupported private function when CFBundle can get
you the same information without having to use such things?
Use CFBundleGetMainBundle followed by CFBundleCopyExecutableURL to get the
location of your executable.
Thanks for the remark, Michael.
-- Andrei
> Andrei Korostelev <and...@korostelev.net> wrote:
> >>
> > Thanks, I have already done it with bundle API like that:
> > [CODE]
> > char myPath[MAXPATHLEN+1];
> > unsigned int myPathLen = MAXPATHLEN;
> > _NSGetExecutablePath(myPath, &myPathLen);
>
> Why are you using an unsupported private function when CFBundle can get
> you the same information without having to use such things?
While I agree that there are better solutions for the OP's task, why do
you claim _NSGetExecutablePath is unsupported? It's documented and until
very recently it was in the sample code Apple provided for a related
task. It's still in other sample code.
Weirdly, that first sample project is completely gone but is still
referenced from several other bits of documentation on the site.
That was my mistake. The leading underscore in the identifier, the
inability of Xcode's documentation search to find it, and a bit of
strangeness in my cursory Google search led me to believe it was a private
function. However, your message prompted me to dig more and I found the
NSModule man page which documents it explicitly.
In any case, if using this API then the buffer size should not be
hardcoded, but should be increased until the function succeeds. But
CFBundle will probably be a nicer way to do things.
> Thanks, I have already done it with bundle API. Any comments?
>
> char myPath[MAXPATHLEN+1];
> unsigned int myPathLen = MAXPATHLEN;
> _NSGetExecutablePath(myPath, &myPathLen);
MAXPATHLEN is evil. There is no need to hardcode such a thing. And
yes, paths can be longer than MAXPATHLEN.
It should be noted that paths longer than MAXPATHLEN tend not to work too
well. There are many APIs which will fail or even crash when given such a
path. This does not change the truth of what you're saying in any way,
it's just something to be aware of when working with paths.
If you can, use FSRefs instead. It's not always practical and not often
easy, but it will avoid the whole path length question and it carries
additional bonuses such as correctly tracking files as they move on many
filesystems.
> Sean McBride <cwa...@cam.org> wrote:
> > In article <1173700366.5...@p10g2000cwp.googlegroups.com>,
> > "Andrei Korostelev" <and...@korostelev.net> wrote:
> >
> >> Thanks, I have already done it with bundle API. Any comments?
> >>
> >> char myPath[MAXPATHLEN+1];
> >> unsigned int myPathLen = MAXPATHLEN;
> >> _NSGetExecutablePath(myPath, &myPathLen);
> >
> > MAXPATHLEN is evil. There is no need to hardcode such a thing. And
> > yes, paths can be longer than MAXPATHLEN.
>
> It should be noted that paths longer than MAXPATHLEN tend not to work too
> well.
Exactly! Because people keep using MAXPATHLEN in their code! Hopefully
that will happen one time less now. :)
Well sure. But when those people include Apple library and kernel
developers you tend to be screwed for a long time. :)