从C ++方法调用Objective-C方法? [英] Calling Objective-C method from C++ method?
问题描述
我有一个类( EAGLView
)调用一个 C ++
类的方法没有问题。现在,问题是,我需要调用 C ++
class a objective-C
函数
[context renderbufferStorage:GL_RENDERBUFFER fromDrawable:(CAEAGLLayer *)self.layer];
/ code>语法。
I have a class (EAGLView
) which calls a method of a C++
class without problems. Now, the problem is that I need to call in that C++
class a objective-C
function
[context renderbufferStorage:GL_RENDERBUFFER fromDrawable:(CAEAGLLayer*)self.layer];
which I cannot do in C++
syntax.
我可以把 Objective-C
$ c> Objective-C 类,首先称为C ++类,但是我需要以某种方式从 C ++
调用该方法,我不知道该怎么做。
I could wrap this Objective-C
call to the same Objective-C
class which in the first place called the C++ class, but then I need to somehow call that method from C++
, and I cannot figure out how to do it.
我试图给一个指针 EAGLView
对象的C ++方法并在我的 C ++
类标题中包括 EAGLView.h
,但我有3999个错误..
I tried to give a pointer to EAGLView
object to the C++ method and include the "EAGLView.h
" in my C++
class header but I got 3999 errors..
那么,我该怎么做呢?一个例子是很好的..我只找到了 C
这样做的例子。
So.. how should I do this? An example would be nice.. I only found pure C
examples of doing this.
推荐答案
如果你仔细地做,你可以混合使用C ++和Objective-C。有几个警告,但一般来说,他们可以混合。如果你想保持它们分开,你可以设置一个标准的C包装函数,给Objective-C对象一个可用的C风格的接口从非Objective-C代码(选择更好的名称为您的文件,我选择了这些名称对于详细程度):
You can mix C++ with Objective-C if you do it carefully. There are a few caveats but generally speaking they can be mixed. If you want to keep them separate, you can set up a standard C wrapper function that gives the Objective-C object a usable C-style interface from non-Objective-C code (pick better names for your files, I have picked these names for verbosity):
#ifndef __MYOBJECT_C_INTERFACE_H__
#define __MYOBJECT_C_INTERFACE_H__
// This is the C "trampoline" function that will be used
// to invoke a specific Objective-C method FROM C++
int MyObjectDoSomethingWith (void *myObjectInstance, void *parameter);
#endif
MyObject.h
MyObject.h
#import "MyObject-C-Interface.h"
// An Objective-C class that needs to be accessed from C++
@interface MyObject : NSObject
{
int someVar;
}
// The Objective-C member function you want to call from C++
- (int) doSomethingWith:(void *) aParameter;
@end
MyObject.mm
MyObject.mm
#import "MyObject.h"
@implementation MyObject
// C "trampoline" function to invoke Objective-C method
int MyObjectDoSomethingWith (void *self, void *aParameter)
{
// Call the Objective-C method using Objective-C syntax
return [(id) self doSomethingWith:aParameter];
}
- (int) doSomethingWith:(void *) aParameter
{
// The Objective-C function you wanted to call from C++.
// do work here..
return 21 ; // half of 42
}
@end
MyCPPClass.cpp < h3>
MyCPPClass.cpp
#include "MyCPPClass.h"
#include "MyObject-C-Interface.h"
int MyCPPClass::someMethod (void *objectiveCObject, void *aParameter)
{
// To invoke an Objective-C method from C++, use
// the C trampoline function
return MyObjectDoSomethingWith (objectiveCObject, aParameter);
}
包装器功能 作为Objective-C类位于同一个 .m
文件中,但它 中存在的文件需要编译作为Objective-C代码 。声明包装函数的头部需要包含在CPP和Objective-C代码中。
The wrapper function does not need to be in the same .m
file as the Objective-C class, but the file that it does exist in needs to be compiled as Objective-C code. The header that declares the wrapper function needs to be included in both CPP and Objective-C code.
(注意:如果Objective-C实现文件被赋予了扩展名 .m,它不会在Xcode下链接,.mm扩展名告诉Xcode期望Objective-C和C ++的组合,即Objective-C ++。)
(NOTE: if the Objective-C implementation file is given the extension ".m" it will not link under Xcode. The ".mm" extension tells Xcode to expect a combination of Objective-C and C++, i.e., Objective-C++.)
您可以使用 PIMPL成语。实现方式略有不同。简单来说,你把包装器函数(在MyObject-C-Interface.h中声明)放在一个带有指向MyClass实例的(private)void指针的类中。
You can implement the above in an Object-Orientented manner by using the PIMPL idiom. The implementation is only slightly different. In short, you place the wrapper functions (declared in "MyObject-C-Interface.h") inside a class with a (private) void pointer to an instance of MyClass.
#ifndef __MYOBJECT_C_INTERFACE_H__
#define __MYOBJECT_C_INTERFACE_H__
class MyClassImpl
{
public:
MyClassImpl ( void );
~MyClassImpl( void );
void init( void );
int doSomethingWith( void * aParameter );
void logMyMessage( char * aCStr );
private:
void * self;
};
#endif
请注意,包装器方法不再需要void指针MyClass的实例;它现在是MyClassImpl的私有成员。 init方法用于实例化MyClass实例;
Notice the wrapper methods no longer require the void pointer to an instance of MyClass; it is now a private member of MyClassImpl. The init method is used to instantiate a MyClass instance;
#import "MyObject-C-Interface.h"
@interface MyObject : NSObject
{
int someVar;
}
- (int) doSomethingWith:(void *) aParameter;
- (void) logMyMessage:(char *) aCStr;
@end
MyObject.mm em>
MyObject.mm (PIMPL)
#import "MyObject.h"
@implementation MyObject
MyClassImpl::MyClassImpl( void )
: self( NULL )
{ }
MyClassImpl::~MyClassImpl( void )
{
[(id)self dealloc];
}
void MyClassImpl::init( void )
{
self = [[MyObject alloc] init];
}
int MyClassImpl::doSomethingWith( void *aParameter )
{
return [(id)self doSomethingWith:aParameter];
}
void MyClassImpl::logMyMessage( char *aCStr )
{
[(id)self doLogMessage:aCStr];
}
- (int) doSomethingWith:(void *) aParameter
{
int result;
// ... some code to calculate the result
return result;
}
- (void) logMyMessage:(char *) aCStr
{
NSLog( aCStr );
}
@end
注意MyClass实例化调用MyClassImpl :: init。你可以在MyClassImpl的构造函数中实例化MyClass,但这通常不是一个好主意。 MyClass实例从MyClassImpl的析构函数中析构。与C风格的实现一样,包装器方法简单地依赖于MyClass的各个方法。
Notice that MyClass is instantiated with a call to MyClassImpl::init. You could instantiate MyClass in MyClassImpl's constructor, but that generally isn't a good idea. The MyClass instance is destructed from MyClassImpl's destructor. As with the C-style implementation, the wrapper methods simply defer to the respective methods of MyClass.
#ifndef __MYCPP_CLASS_H__
#define __MYCPP_CLASS_H__
class MyClassImpl;
class MyCPPClass
{
enum { cANSWER_TO_LIFE_THE_UNIVERSE_AND_EVERYTHING = 42 };
public:
MyCPPClass ( void );
~MyCPPClass( void );
void init( void );
void doSomethingWithMyClass( void );
private:
MyClassImpl * _impl;
int _myValue;
};
#endif
MyCPPClass.cpp em>
MyCPPClass.cpp (PIMPL)
#include "MyCPPClass.h"
#include "MyObject-C-Interface.h"
MyCPPClass::MyCPPClass( void )
: _impl ( NULL )
{ }
void MyCPPClass::init( void )
{
_impl = new MyClassImpl();
}
MyCPPClass::~MyCPPClass( void )
{
if ( _impl ) { delete _impl; _impl = NULL; }
}
void MyCPPClass::doSomethingWithMyClass( void )
{
int result = _impl->doSomethingWith( _myValue );
if ( result == cANSWER_TO_LIFE_THE_UNIVERSE_AND_EVERYTHING )
{
_impl->logMyMessage( "Hello, Arthur!" );
}
else
{
_impl->logMyMessage( "Don't worry." );
}
}
现在通过私有实现访问MyClass的调用MyClassImpl。如果您正在开发便携式应用程序,这种方法可能是有利的;你可以简单地将一个特定于其他平台的MyClass的实现交换出来,但是老实说,这是否是一个更好的实现更是一个品味和需求的问题。
You now access calls to MyClass through a private implementation of MyClassImpl. This approach can be advantageous if you were developing a portable application; you could simply swap out the implementation of MyClass with one specific to the other platform ... but honestly, whether this is a better implementation is more a matter of taste and needs.
这篇关于从C ++方法调用Objective-C方法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!