Вызов метода Objective-C из функции C ++? - PullRequest
1 голос
/ 28 марта 2012

Я взял это из ответа на вопрос о том, как вызвать методjective-c из метода C ++

Это работает нормально.

MyObject-C-Interface.h

 #ifndef __MYOBJECT_C_INTERFACE_H__
 #define __MYOBJECT_C_INTERFACE_H__ 1

 int MyObjectDoSomethingWith (void *myObjectInstance, void *parameter);

 #endif

MyObject.h

#import "MyObject-C-Interface.h"

@interface MyObject : NSObject
{
     int someVar;
}

- (int) doSomethingWith:(void *) aParameter;
@end

MyObject.mm

 #import "MyObject.h"

 @implementation MyObject

 int MyObjectDoSomethingWith (void *self, void *aParameter)
 {
     return [(id) self doSomethingWith:aParameter];
 }

 - (int) doSomethingWith:(void *) aParameter
 {
     // ... some code
     return 1;
 }

 @end

MyCPPClass.cpp

#include "MyCPPClass.h"
#include "MyObject-C-Interface.h"

int MyCPPClass::someMethod (void *objectiveCObject, void *aParameter)
{
     return MyObjectDoSomethingWith (objectiveCObject, aParameter);
}

NOW , если я использую что-то вроде

MyObject-C-Interface.h

 #ifndef __MYOBJECT_C_INTERFACE_H__
 #define __MYOBJECT_C_INTERFACE_H__ 1

 @class MyObject;

 int MyObjectDoSomethingWith (MyObject* myObjectInstance, void *parameter);

 #endif

Мой вопрос вместо использования void * myObjectInstance , если я использую MyObject * myObjectInstance .

, он выдает эту ошибку
ошибка: ожидаемый неквалифицированный идентификатор [1] : строка @class и
ошибка: использование необъявленного идентификатора 'MyObject' [3] в строке прототипа функции

Help!!!!

1 Ответ

3 голосов
/ 28 марта 2012

Ошибка связи:

Ошибка связи связана с тем, как C ++ искажает имена функций, чего не делает C.Это на самом деле не имеет ничего общего с Objective-C.В частности,

int MyObjectDoSomethingWith (void *myObjectInstance, void *parameter);

в C или Objective-C (в OSX) экспортируется в компоновщик с именем _MyObjectDoSomethingWith.Функция с тем же именем и прототипом, скомпилированная с помощью компилятора C ++ или Objective-C ++, известна компоновщику как __Z23MyObjectDoSomethingWithPvS_.Это называется «искажение имени», и оно кодирует типы параметров.В противном случае перегрузка функций не сработает, поскольку функции с разными типами параметров, но одно и то же имя не могут быть различены.Чтобы вызвать функцию, определенную в C из C ++, вы должны пометить прототип так, чтобы ожидалась связь C, и она не поменяла имя этой конкретной перегрузки функции.

Вам понадобитсясообщить компилятору C ++, что он должен обрабатывать ее как функцию C с использованием extern "C", например:

#ifndef MYOBJECT_C_INTERFACE_H
#define MYOBJECT_C_INTERFACE_H

#ifdef __cplusplus
extern "C" {
#endif

int MyObjectDoSomethingWith (void *myObjectInstance, void *parameter);

#ifdef __cplusplus
}
#endif

#endif

или следующим образом:

#ifndef MYOBJECT_C_INTERFACE_H
#define MYOBJECT_C_INTERFACE_H

#ifdef __cplusplus
#define CFUN extern "C"
#else
#define CFUN
#endif

CFUN int MyObjectDoSomethingWith (void *myObjectInstance, void *parameter);

#endif

@ объявление класса compileошибка (, пожалуйста, не задавайте более одного вопроса одновременно ):

Вы пытаетесь #include "MyObject-C-Interface.h", который содержит декларацию Objective C @class forwardиз MyCPPClass.cpp , который будет скомпилирован как чистый C ++.Директивы Objective-C - это в основном синтаксические ошибки в C ++, поэтому вы не можете этого сделать.Чтобы обойти объекты Objective C в чистом C ++ или C, вам нужно будет использовать тип id.Для этого вам понадобится #include <objc/objc.h>, так как id не определено по умолчанию в C или C ++.

* Кроме того, пожалуйста, не ставьте перед своими именами два подчеркивания: __ - такие именазарезервированы. *

...