Starting An App With String Arguments (C++)

Discussion in 'Mac Programming' started by ajm113, Jan 23, 2011.

  1. ajm113 macrumors newbie

    Joined:
    Jan 16, 2011
    #1
    Hello, I'm coming from a Windows background and I want to start an app I developed for my "main" application to start, but in order for the app I want to start to work correctly I have to pass string command line arguments.

    Here is how I thought passing command line argument would have worked.

    My Application.app "InputFile.txt" "outputFile.txt" "1"

    I tried using things such as this command such as 'open', but it keeps thinking I'm opening more then one file and I was thinking I could just use a working command I get going off the terminal into the system command.

    I also have tried the fork and execv example from the cplusplus.com for starting executables, but I get these errors:

    Code:
    The process has forked and you cannot use this CoreFoundation functionality safely. You MUST exec().
    Break on __THE_PROCESS_HAS_FORKED_AND_YOU_CANNOT_USE_THIS_COREFOUNDATION_FUNCTIONALITY___YOU_MUST_EXEC__() to debug.
    The process has forked and you cannot use this CoreFoundation functionality safely. You MUST exec().
    Break on __THE_PROCESS_HAS_FORKED_AND_YOU_CANNOT_USE_THIS_COREFOUNDATION_FUNCTIONALITY___YOU_MUST_EXEC__() to debug.
    
    I'm guesting it's because I'm using a higher level API such as wxMac that is causing those errors.

    Here is my source code too:
    Code:
    		char *my_args[6] = {"MyApp.app", "InputFile.txt", (char*)SavePath.c_str(), "1", NULL};
    		pid_t pid;
    		
    		switch ((pid = fork())) {
    			case -1:
    				cout << "Fork Error!" << endl;
    				break;
    			case 0:
    				execv("MyApp.app", my_args);
    			default:
    				cout << "This is a message from the parent!" << endl;
    				break;
    		}
    
    Thank you for reading my post.
     
  2. gnasher729 macrumors P6

    gnasher729

    Joined:
    Nov 25, 2005
    #2
    I'd go to developer.apple.com, type "execv" into the search box, and go from there.
     
  3. ajm113 thread starter macrumors newbie

    Joined:
    Jan 16, 2011
    #3
    Well ... After a couple of hours going through google and reading documentation I keep running into problems and so far I made this code:

    Code:
    		char *my_args[] = {(char*)m_AppDirectory.AppendWorkingDirectory("/Digital Symbol Studio Renderer.app").c_str(), (char*)m_AppDirectory.AppendWorkingDirectory("/Projects/Temp_Project33222356.saf").c_str(), (char*)ImageSavePath.c_str(), "1", NULL};
    		char *newenviron[] = { NULL };
    
    		cout << m_AppDirectory.AppendWorkingDirectory("/Digital Symbol Studio Renderer.app").c_str() << endl;
    		 if(execve(m_AppDirectory.AppendWorkingDirectory("/Digital Symbol Studio Renderer.app").c_str(), my_args, newenviron) == -1)
    		 {
    			perror("execve");   /* execve() only returns on error */
    		 }
    
    
    I keep getting "permission denied" error from perror is this saying this because my application doesn't have permission to start applications?
     
  4. lee1210 macrumors 68040

    lee1210

    Joined:
    Jan 10, 2005
    Location:
    Dallas, TX
    #4
    You are trying to execute a directory, which isn't going to fly. .app bundles are directories that contain an app's resources and executable. There are a few ways to address this, one being to get the actual path to the executable inside the bundle. I think another is to run the open command passing the path to the bundle, but i don't know this for certain.

    -Lee
     
  5. ajm113, Jan 23, 2011
    Last edited: Jan 23, 2011

    ajm113 thread starter macrumors newbie

    Joined:
    Jan 16, 2011
    #5
    Ohh! I see, that makes sense now it's not working correctly, but even if I try to start the application directly(Unix Executable) I get a crash and all I did was remove .app since Mac Executables I build don't have one.

    Code:
    being debugged was signaled while in a function called from GDB.
    GDB has restored the context to what it was before the call.
    To change this behavior use "set unwindonsignal off"
    Evaluation of the expression containing the function (gdb_objc_startDebuggerMode) will be abandoned.)
    
    I would love just to use the open command directly using system function, but my 'Windows' style syntax is messing the command making it think I'm wanting to 'open' more then one file at a time, but really I'm trying to send arguments that are paths to file locations I want my application I'm trying to start.

    Apologize for asking low level questions, but Macs are a completely different environment for me, so I'm trying to learn as I go.
     
  6. lee1210 macrumors 68040

    lee1210

    Joined:
    Jan 10, 2005
    Location:
    Dallas, TX
    #6
    Can you show us this amended code? open doesn't seem to play well with passing down arguments so scratch that.

    -Lee
     
  7. ajm113 thread starter macrumors newbie

    Joined:
    Jan 16, 2011
    #7
    Well it's pretty much the same code I posted last time, but here I'll remove the "AppendWorkingDirectory" functions and replace what it returns so you have a clear understanding whats going on.

    Code:
    		char *my_args[] = {"/Users/andrewmcrobb/Documents/Digital Symbol Studio (wxMac)/build/Release/Digital Symbol Studio Renderer", (char*)m_AppDirectory.AppendWorkingDirectory("/Projects/Temp_Project33222356.saf").c_str(), (char*)ImageSavePath.c_str(), "1", NULL};
    		char *newenviron[] = { NULL };
    
    		cout << m_AppDirectory.AppendWorkingDirectory("/Digital Symbol Studio Renderer").c_str() << endl;
    		 if(execve("/Users/andrewmcrobb/Documents/Digital Symbol Studio (wxMac)/build/Release/Digital Symbol Studio Renderer", my_args, newenviron) == -1)
    		 {
    			perror("execve");   /* execve() only returns on error */
    		 }
    
    I'm just wondering, why don't Unix Executable built by Xcode have a file extension such as .exe and instead of having no file extension?
     
  8. lee1210 macrumors 68040

    lee1210

    Joined:
    Jan 10, 2005
    Location:
    Dallas, TX
    #8
    I can peek at the code later, but I can answer this now. That's how unix does things. Executable binary files just don't have an extension. You can mark other things, such as a perl script with a .pl extension, as executable as well, but that's really a text file not a binary file. Generally an extension tells you what sort of file something is so you know what to open it with. You don't really open an executable binary with something, you execute the code.

    .exe has been used on a few different systems, but the most popular is DOS and Windows. Systems have been doing things differently than this much longer than there has been DOS. What you should be asking is "why did DOS decide executables needed to have an extension?" =).

    -Lee

    EDIT: While we're at it, if you run this from terminal with the given arguments (minus [0]) do you get the expected behavior?
     
  9. ajm113 thread starter macrumors newbie

    Joined:
    Jan 16, 2011
    #9
    Ohh okay, that makes a lot of sense now. :)

    Thank you for clearing that up, that was getting to me.

    Well not really... Like I mentioned I've been kinda using Windows style syntax and I'm not sure how to pass string arguments through terminal even. So I've been pretty much passing arguments like so:

    "./Digital Symbol Studio Renderer "Project/someFile.txt" "outputFile.txt" "1""

    I even tried single quotes and those don't work aether, I keep getting the "No such file directory" error, but my terminal command works perfectly fine without the arguments. What do I use for stringed arguments in the Terminal, I spent hours looking this up, but it's got me no where.
     
  10. lee1210 macrumors 68040

    lee1210

    Joined:
    Jan 10, 2005
    Location:
    Dallas, TX
    #10
    This looks like a quot-astrophe. I don't know what all the paths should be, but:
    "/Users/andrewmcrobb/Documents/Digital Symbol Studio (wxMac)/build/Release/Digital Symbol Studio Renderer" "/Users/andrewmcrobb/Documents/Digital Symbol Studio (wxMac)/Project/someFile.txt" outputFileName.txt 1

    Might work? You might need to fix the path to the input file. You can quote things so you can have spaces without escaping them like this:
    /Users/tom/the\ directory/

    Once you get exactly the right command working in terminal you should be able to get the right thing to execve. I don't know what AppendWorkingDirectory is or what it does, but if it's adding a trailing '/' it may not be doing what you want. You may want to write a little loop to print out your my_args array to see what you're trying to run to be sure it's what you intend.

    -Lee
     
  11. ajm113 thread starter macrumors newbie

    Joined:
    Jan 16, 2011
    #11
    Perfect thank you so much!! My project is 100% completely converted on the Mac you saved me so much time! :)

    *high fives*

    Now all I need to do is fix or add features and all I have to do is copy and paste code snippits from Mac to Windows or viceversa as I go. ;)

    Thanks again, you rock!
     
  12. kainjow Moderator emeritus

    kainjow

    Joined:
    Jun 15, 2000
    #12
    FYI, if you're launching a .app, the preferred way is through Launch Services. See LSOpenApplication().
     
  13. lee1210 macrumors 68040

    lee1210

    Joined:
    Jan 10, 2005
    Location:
    Dallas, TX
    #13

Share This Page