Вызов класса Objective-C из базового проекта C, xcode - PullRequest
1 голос
/ 23 сентября 2011

Я пытаюсь реализовать приложение какао для обнаружения USB.Всякий раз, когда пользователь подключает USB, который он автоматически обнаружил, вся эта часть программы C (Normal C) работает нормально.

Мне нужно, если система обнаруживает определенное устройство USB, я хочу вызвать другое приложение (т.е.другое приложение какао) с использованием системной функции.Я открываю это приложение, но моя проблема в том, что если пользователь удаляет это USB-устройство (это также обнаруживается в программе на языке C), я хочу автоматически закрыть второе приложение.Класс / target-c в первом приложении, можно ли вызвать этот класс изнутри программы на C?

Ответы [ 3 ]

1 голос
/ 23 сентября 2011

Один класс, который вы можете использовать для этого, - NSDistributedNotificationCenter. Ваша программа на C должна будет публиковать уведомления, а другие ваши программы будут подписываться на них. Сценарий будет выглядеть так:

  • Второе приложение: в регистре запуска для получения сообщений «USB Device Removed»
  • C Программа: удалить удаленное USB-устройство
  • C Программа: после уведомления "USB Device Removed"
  • Второе приложение: получает уведомление «USB-устройство удалено»
  • Второе приложение: само по себе

Конечно, ваша C-программа теперь стала бы целевой-C-программой. Существует также альтернатива C, которая CFNotificationCenterGetDistributedCenter.

1 голос
/ 23 сентября 2011

Если объект уже существует и вы можете передать на него указатель, вы можете использовать функцию времени выполнения Objective C objc_msgSend.Например:

#include <objc/runtime.h>
#include <objc/message.h>

void sendDoneToApp(id app)
{
    /* [app done]; */

    /* get selector for "done" */
    SEL doneSel = sel_registerName("done");

    /* cast objc_msgSend to the type we need */
    void (*sendNoArgsNoRet)(id obj, SEL selector) = (void (*)(id, SEL))objc_msgSend;

    /* send the message */
    sendNoArgsNoRet(app, doneSel);
}
0 голосов
/ 23 сентября 2011

Да, это возможно. Например, вы можете посмотреть, как libdispatch / Grand Central Dispatch управляет этим.

Основная идея - передать указатели функций C + указатели void в вашу библиотеку C. И тогда в переданной функции вы можете вызывать функции Obj-C. Пример:

struct test_s {
    NSString *my_string;
};

void my_function(void *data) {
    struct test_s *context = data;
    NSLog(@"%@", [@"Hello " stringByAppendingString:context->my_string];
}

void main(void) {
    struct test_s context = { @"World!" };

    /* dispatch_sync_f is a C function unaware of Obj-C */
    dispatch_sync_f(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0),
                    &context,
                    my_function);
}
...