Professional Web Applications Themes

Communication between (shell) tool and Cocoa application ? - Mac Programming

What is the best way to exchange info between a standard C tool and Cocoa application ? Most of the time the application and the tool does nothing (just wait). Is pipe (FIFO) good choice for it ?...

  1. #1

    Default Communication between (shell) tool and Cocoa application ?

    What is the best way to exchange info between a standard C tool
    and Cocoa application ?

    Most of the time the application and the tool does nothing (just wait).
    Is pipe (FIFO) good choice for it ?
    Alain Guest

  2. #2

    Default Re: Communication between (shell) tool and Cocoa application ?

    Alain Birtz a écrit :
     

    Yes and no, you must use NSPipe, NSTask and NSFileHandle like this (for
    example) :

    interface MyController: NSObject
    {

    ....


    //---- communication avec le process 'lp'
    NSTask *lp;
    NSPipe *toPipe;
    NSPipe *fromPipe;
    NSFileHandle *to_lp;
    NSFileHandle *from_lp;
    }
    -(BOOL) printFile:(NSString *)file withType:(NSString *)type

    end

    implementation MyController: NSObject

    //--------------------------------------------------------------------------
    -(BOOL) printFile:(NSString *)file withType:(NSString *)type
    {
    NSString *strCmd = nil;

    if( [type isEqualToString:ePSType] )
    strCmd = [[NSString alloc] initWithFormat:"lp -oraw '%'", file];
    else if( [type isEqualToString:eEPSType] )
    strCmd = [[NSString alloc] initWithFormat:"lp -oraw '%'", file];
    else if( [type isEqualToString:ePDFType] )
    strCmd = [[NSString alloc] initWithFormat:"lp '%'", file];
    else {
    return NO;
    }
    NSData *sendData = [[strCmd stringByAppendingString:"\n"]
    dataUsingEncoding:NSUTF8StringEncoding
    allowLossyConversion:NO];

    //---- on transmet la commande à la tâche 'LIFServ_lp'
    [to_lp writeData:sendData];

    //---- on fait du ménage avant de quitter l'impression
    [strCmd release];

    return YES;
    }


    //--------------------------------------------------------------------------
    -(BOOL) doSomeThing
    {
    NSString *path = nil;

    path = [[NSBundle mainBundle] pathForAuxiliaryExecutable:ktPrintPS_lp];
    if(!path) goto DONE;

    toPipe = [NSPipe pipe];
    fromPipe = [NSPipe pipe];

    to_lp = [toPipe fileHandleForWriting];
    from_lp = [fromPipe fileHandleForReading];

    lp = [[NSTask alloc] init];
    [lp setLaunchPath:path];

    [lp setStandardOutput:fromPipe];
    [lp setStandardInput:toPipe];

    [lp launch];

    [[NSNotificationCenter defaultCenter]
    addObserver:self
    selector:selector(gotData:)
    name:NSFileHandleReadCompletionNotification
    object:from_lp];

    [from_lp readInBackgroundAndNotify];

    return YES;

    DONE:
    return NO;
    }

    end




    -----

    //---------------------------------------------------------------------------------
    int main(int argc, char *argv[])
    //---------------------------------------------------------------------------------
    {
    short err = 0;

    char command[ktMAXBUFIN+1];

    while(fgets(command, ktMAXBUFIN, stdin)) {
    err = evaluateCommand(command);
    //---- if err do some thing
    }

    exit(0);
    }

    //---------------------------------------------------------------------------------
    static int evaluateCommand(char *cmd)
    //---------------------------------------------------------------------------------
    {
    short err;
    err = system(cmd); //---- lancer la commande système...

    return err;
    }


    --
    JMM

    replace 'no_spam' by 'free' to reply

    Jean-Michel Guest

  3. #3

    Default Re: Communication between (shell) tool and Cocoa application ?

    Alain Birtz a écrit :
     

    Yes and no, you must use NSPipe, NSTask and NSFileHandle like this (for
    example) :

    interface MyController: NSObject
    {

    ....


    //---- communication avec le process 'lp'
    NSTask *lp;
    NSPipe *toPipe;
    NSPipe *fromPipe;
    NSFileHandle *to_lp;
    NSFileHandle *from_lp;
    }
    -(void) foo:(void);
    -(BOOL) printFile:(NSString *)file withType:(NSString *)type;
    -(BOOL) setupPipeForPrint;

    end

    implementation MyController: NSObject

    //---- initialiser le pipe
    -(void) foo:(void)
    {
    [self setupPipeForPrint];
    }

    //--------------------------------------------------------------------------
    -(BOOL) printFile:(NSString *)file withType:(NSString *)type
    {
    NSString *strCmd = nil;

    if( [type isEqualToString:ePSType] )
    strCmd = [[NSString alloc] initWithFormat:"lp -oraw '%'", file];
    else if( [type isEqualToString:eEPSType] )
    strCmd = [[NSString alloc] initWithFormat:"lp -oraw '%'", file];
    else if( [type isEqualToString:ePDFType] )
    strCmd = [[NSString alloc] initWithFormat:"lp '%'", file];
    else {
    return NO;
    }
    NSData *sendData = [[strCmd stringByAppendingString:"\n"]
    dataUsingEncoding:NSUTF8StringEncoding
    allowLossyConversion:NO];

    //---- on transmet la commande à la tâche 'LIFServ_lp'
    [to_lp writeData:sendData];

    //---- on fait du ménage avant de quitter l'impression
    [strCmd release];

    return YES;
    }


    //--------------------------------------------------------------------------
    -(BOOL) setupPipeForPrint
    {
    NSString *path = nil;

    path = [[NSBundle mainBundle] pathForAuxiliaryExecutable:ktPrintPS_lp];
    if(!path) goto DONE;

    toPipe = [NSPipe pipe];
    fromPipe = [NSPipe pipe];

    to_lp = [toPipe fileHandleForWriting];
    from_lp = [fromPipe fileHandleForReading];

    lp = [[NSTask alloc] init];
    [lp setLaunchPath:path];

    [lp setStandardOutput:fromPipe];
    [lp setStandardInput:toPipe];

    [lp launch];

    [[NSNotificationCenter defaultCenter]
    addObserver:self
    selector:selector(gotData:)
    name:NSFileHandleReadCompletionNotification
    object:from_lp];

    [from_lp readInBackgroundAndNotify];

    return YES;

    DONE:
    return NO;
    }

    end




    -----

    //---------------------------------------------------------------------------------
    int main(int argc, char *argv[])
    //---------------------------------------------------------------------------------
    {
    short err = 0;

    char command[ktMAXBUFIN+1];

    while(fgets(command, ktMAXBUFIN, stdin)) {
    err = evaluateCommand(command);
    //---- if err do some thing
    }

    exit(0);
    }

    //---------------------------------------------------------------------------------
    static int evaluateCommand(char *cmd)
    //---------------------------------------------------------------------------------
    {
    short err;
    err = system(cmd); //---- lancer la commande système...

    return err;
    }


    --
    JMM

    replace 'no_spam' by 'free' to reply


    Jean-Michel Guest

  4. #4

    Default Re: Communication between (shell) tool and Cocoa application ?

    ca (Alain Birtz) wrote in message news:<168.1.3>... 

    Using BSD tools we get

    FILE *fp;
    char buffer[256];

    fp = popen("ls -als","r");
    if( fp != NULL )
    {
    while( fgets(buffer,255,fp) != NULL )
    {
    printf("%s",buffer);
    }
    pclose(fp);
    }
    Jim Guest

  5. #5

    Default Re: Communication between (shell) tool and Cocoa application ?

    Alain Birtz wrote: 

    See the NSTask class.

    -jcr
    John Guest

  6. #6

    Default Re: Communication between (shell) tool and Cocoa application ?

    What do you guys think of CFMessagePorts? I'm preparing to implement
    one now.

    Communications between a prefpane and a tool is working quite well.
    But what about to a Cocoa app? In my case, I need enough throughput to
    simulate mouse movements and clicks without skipping. Is this
    reasonable from a CFMessagePort?

    Thanks!

    nlexcom
    Neil Guest

  7. #7

    Default Re: Communication between (shell) tool and Cocoa application ?

    Neil Alexander wrote: 

    System Preferences *is* a Cocoa app.

    -jcr
    John Guest

  8. #8

    Default Re: Communication between (shell) tool and Cocoa application ?

    In article <168.1.3>,
    ca (Alain Birtz) wrote:
     

    It's impossible to give a good answer with no idea of what kind of
    communication you need. I've used, at various times, pipes, sockets,
    distributed notifications, and distributed objects. No single solution
    is right for all cases.

    --
    Tom "Tom" Harrington
    Macaroni, Automated System Maintenance for Mac OS X.
    Version 2.0: Delocalize, Repair Permissions, lots more.
    See http://www.atomicbird.com/
    Tom Guest

  9. #9

    Default Re: Communication between (shell) tool and Cocoa application ?

    I guess I wasn't too clear above. Yes, I know that a pref pane is a
    cocoa app. But you don't need much bandwidth for a pref pane.

    Anyway, I implemented my project using CFMessagePort. The call's
    return is the actual data. We're talking very small amount of data per
    record - about 50 bytes or so.

    Anyway, I'm calling it around 50 x per second, and performance is fine
    on my 667 mhz TiBook. My customer is using a 350Mhz iBook (G4) I
    believe, and it's working fine for him, too.

    We don't have to be backwards compatible before G4's, so we should be
    ok.

    So for small amounts of data from an HID Userland device driver, all
    works AOK.

    nlexcom
    Neil Guest

Similar Threads

  1. Replies: 0
    Last Post: October 9th, 07:36 PM
  2. application communication in xml without webservices?
    By Davey in forum ASP.NET Web Services
    Replies: 3
    Last Post: November 24th, 12:26 AM
  3. Replies: 4
    Last Post: January 16th, 06:53 AM
  4. Replies: 10
    Last Post: October 25th, 11:50 AM

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139