0

I get strange code errors when I rename the following command line program from main.m to main.mm. Works just fine as main.m. Anyone know why?

https://stackoverflow.com/a/36469891/105539

SOURCE

#import <Foundation/Foundation.h>

void detectNewFile (
    ConstFSEventStreamRef streamRef,
    void *clientCallBackInfo,
    size_t numEvents,
    void *eventPaths,
    const FSEventStreamEventFlags eventFlags[],
    const FSEventStreamEventId eventIds[])
{
    int i;
    char **paths = eventPaths;

    printf("GOT AN EVENT!!!!\n");
    for (i=0; i<numEvents; i++) {
        printf("Change %llu in %s, flags %u\n", eventIds[i], paths[i], (unsigned int)eventFlags[i]);
    }
}

int main(int argc, const char * argv[]) {
    @autoreleasepool {

        short nPathCount = 2;
        CFStringRef mypath[nPathCount];
        mypath[0] = CFSTR("/Users/mike/Documents");
        mypath[1] = CFSTR("/Users/mike/Downloads");
        CFArrayRef pathsToWatch = CFArrayCreate(NULL, (const void **)&mypath, nPathCount, NULL);
        void *callbackInfo = NULL;
        CFAbsoluteTime latency = 1.0; // seconds

        FSEventStreamRef hStream = FSEventStreamCreate(NULL,
            &detectNewFile,
            callbackInfo,
            pathsToWatch,
            kFSEventStreamEventIdSinceNow,
            latency,
            kFSEventStreamCreateFlagFileEvents
        );

        FSEventStreamScheduleWithRunLoop(hStream, CFRunLoopGetCurrent(),         kCFRunLoopDefaultMode);
        FSEventStreamStart(hStream);
        printf("Waiting on new file creations...\n");
        CFRunLoopRun(); // runs in an endless loop, only letting the callback function run

    } // end autorelease pool
    return 0;
}

ERRORS

FOR: 
        char **paths = eventPaths;

Cannot initialize a variable of type 'char **' with an lvalue of type 'void *'

FOR: 
        FSEventStreamRef hStream = FSEventStreamCreate(NULL,
            &detectNewFile,
            callbackInfo,
            pathsToWatch,
            kFSEventStreamEventIdSinceNow,
            latency,
            kFSEventStreamCreateFlagFileEvents
        );

No matching function for call to 'FSEventStreamCreate'
Community
  • 1
  • 1
Volomike
  • 23,743
  • 21
  • 113
  • 209

1 Answers1

1

Thanks to @johnelemans, I found the problems. In C, it's legal to have automatic casting from void * to char **, but not in C++, which is what the .mm file would switch this into. The fix is to use casting:

char **paths = (char **)eventPaths;

Then, on the FSEventStreamCreate, it didn't like the void * instead of this:

FSEventStreamContext *callbackInfo = NULL;

...and didn't like the CFAbsoluteTime instead of:

CFTimeInterval latency = 1.0; // seconds

Then, you need to add CoreServices.framework library to the build steps.

I made those changes and it compiles now.

Volomike
  • 23,743
  • 21
  • 113
  • 209