เรียกเมธอด Objective-C จากฟังก์ชันสมาชิก C ++?


111

ฉันมีคลาส ( EAGLView) ซึ่งเรียกใช้ฟังก์ชันสมาชิกของC++คลาสโดยไม่มีปัญหา ตอนนี้ปัญหาคือฉันต้องเรียกในC++คลาสobjective-C function [context renderbufferStorage:GL_RENDERBUFFER fromDrawable:(CAEAGLLayer*)self.layer];นั้นซึ่งฉันไม่สามารถทำได้ในC++รูปแบบไวยากรณ์

ฉันสามารถตัดการObjective-Cเรียกนี้เป็นObjective-Cคลาสเดียวกันซึ่งในตอนแรกเรียกว่าคลาส C ++ แต่ฉันต้องเรียกวิธีนั้นจากวิธีC++ใดและฉันไม่สามารถหาวิธีการได้

ฉันพยายามให้ตัวชี้EAGLViewคัดค้านฟังก์ชันสมาชิก C ++ และรวม " EAGLView.h" ไว้ในC++ส่วนหัวของคลาส แต่ฉันพบข้อผิดพลาด 3999 ..

แล้ว.. จะทำอย่างไรดี? ตัวอย่างจะดี .. ฉันพบเพียงCตัวอย่างที่บริสุทธิ์ของการทำเช่นนี้

คำตอบ:


204

คุณสามารถผสม C ++ กับ Objective-C ได้หากคุณทำอย่างระมัดระวัง มีข้อแม้บางประการ แต่โดยทั่วไปแล้วสามารถใช้ผสมกันได้ หากคุณต้องการแยกมันออกจากกันคุณสามารถตั้งค่าฟังก์ชัน C wrapper มาตรฐานที่ให้ Objective-C อินเทอร์เฟซสไตล์ C ที่ใช้งานได้จากโค้ดที่ไม่ใช่ Objective-C (เลือกชื่อที่ดีกว่าสำหรับไฟล์ของคุณฉันได้เลือกชื่อเหล่านี้แล้ว สำหรับ verbosity):

MyObject-C-Interface.h

#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

#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

#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

#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);
}

ฟังก์ชัน wrapper ไม่จำเป็นต้องอยู่ใน.mไฟล์เดียวกันกับคลาส Objective-C แต่ไฟล์ที่มีอยู่จะต้องคอมไพล์เป็นโค้ด Objective-Cความต้องการที่จะรวบรวมเป็นรหัสส่วนหัวที่ประกาศฟังก์ชัน wrapper จะต้องรวมไว้ในโค้ด CPP และ Objective-C

(หมายเหตุ: หากไฟล์การใช้งาน Objective-C ได้รับส่วนขยาย ".m" จะไม่เชื่อมโยงภายใต้ Xcode ส่วนขยาย ".mm" บอกให้ Xcode คาดว่าจะมีการรวมกันของ Objective-C และ C ++ นั่นคือ Objective-C ++ )


คุณสามารถใช้ข้างต้นในลักษณะเชิงวัตถุโดยใช้สำนวน PIMPLสำนวนการนำไปใช้แตกต่างกันเพียงเล็กน้อย ในระยะสั้นคุณวางฟังก์ชัน wrapper (ประกาศใน "MyObject-C-Interface.h") ภายในคลาสที่มีตัวชี้โมฆะ (ส่วนตัว) ไปยังอินสแตนซ์ของ MyClass

MyObject-C-Interface.h (PIMPL)

#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

สังเกตว่าวิธีการ wrapper ไม่ต้องการตัวชี้โมฆะในอินสแตนซ์ของ MyClass อีกต่อไป ตอนนี้เป็นสมาชิกส่วนตัวของ MyClassImpl วิธีการ init ใช้เพื่อสร้างอินสแตนซ์อินสแตนซ์ MyClass

MyObject.h (PIMPL)

#import "MyObject-C-Interface.h"

@interface MyObject : NSObject
{
    int someVar;
}

- (int)  doSomethingWith:(void *) aParameter;
- (void) logMyMessage:(char *) aCStr;

@end

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 คุณสามารถสร้างอินสแตนซ์ MyClass ในตัวสร้างของ MyClassImpl ได้ แต่โดยทั่วไปแล้วไม่ใช่ความคิดที่ดี อินสแตนซ์ MyClass ถูกทำลายจากตัวทำลายของ MyClassImpl เช่นเดียวกับการใช้งานรูปแบบ C วิธีการห่อหุ้มจะเลื่อนไปตามวิธีการของ MyClass ตามลำดับ

MyCPPClass.h (PIMPL)

#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 (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 กับแพลตฟอร์มที่เฉพาะเจาะจงไปยังแพลตฟอร์มอื่น ๆ ได้ ...


6
สวัสดีฉันลองแล้ว แต่ได้รับข้อผิดพลาดในการเชื่อมโยงโดยระบุว่าไม่พบสัญลักษณ์ กล่าวคือไม่พบ MyObjectDoSomethingWith ความคิดใด ๆ

3
คุณอาจต้องเพิ่มextern "C"ก่อนint MyObjectDoSomethingWith
dreamlax

2
ลองแล้วไม่ได้ผลและมันก็สมเหตุสมผลเพราะใช้ "C" ภายนอกเมื่อเราต้องการเรียกใช้ฟังก์ชัน C ++ จาก C ในกรณีนี้เรากำลังเรียกฟังก์ชัน C จาก C ++ ไม่ใช่เหรอ?

6
นอกจากนี้ objectiveCObject จะสร้างอินสแตนซ์ใน MyCPPClass.cpp ได้อย่างไร
Raffi Khatchadourian

2
@dreamlax สุดยอดที่กำลังรวบรวม แต่ไม่รู้จะเรียกแบบนั้นว่า "someMethod" ซึ่งควรเป็นพารามิเตอร์ที่ควรเพิ่มใน: int MyCPPClass :: someMethod (void * objectiveCObject, void * aParameter) ???
the_moon

15

คุณสามารถคอมไพล์โค้ดของคุณเป็น Objective-C ++ ได้วิธีที่ง่ายที่สุดคือเปลี่ยนชื่อ. cpp เป็น. mm จากนั้นจะคอมไพล์อย่างถูกต้องหากคุณรวมEAGLView.h(คุณได้รับข้อผิดพลาดจำนวนมากเนื่องจากคอมไพเลอร์ C ++ ไม่เข้าใจคำสำคัญใด ๆ ของ Objective-C) และคุณสามารถ (ส่วนใหญ่) ผสม Objective-C และ C ++ อย่างไรก็ได้ ชอบ.


คุณจะได้รับทุกคนรวบรวมข้อผิดพลาดในการนี้ ++ ไฟล์ C หรือว่าพวกเขาในบางไฟล์อื่น c ++ ที่เกิดขึ้นรวมถึงนี้ c ++ หัว?
Jesse Beder

ดูเหมือนว่าฉันไม่สามารถรวม EAGLView.h ในไฟล์ส่วนหัว C ++ ได้เนื่องจากด้วยเหตุผลบางประการคาดว่ารหัส Objective C คือ C ++ และไม่เข้าใจ @ + สัญลักษณ์อื่น ๆ
juvenis

12

วิธีแก้ปัญหาที่ง่ายที่สุดคือเพียงแค่บอกให้ Xcode รวบรวมทุกอย่างเป็น Objective C ++

กำหนดการตั้งค่าโปรเจ็กต์หรือเป้าหมายของคุณสำหรับ Compile Sources As to Objective C ++ และคอมไพล์ใหม่

จากนั้นคุณสามารถใช้ C ++ หรือ Objective C ได้ทุกที่ตัวอย่างเช่น:

void CPPObject::Function( ObjectiveCObject* context, NSView* view )
{
   [context renderbufferStorage:GL_RENDERBUFFER fromDrawable:(CAEAGLLayer*)view.layer]
}

สิ่งนี้มีผลเช่นเดียวกับการเปลี่ยนชื่อไฟล์ต้นฉบับทั้งหมดของคุณจาก. cpp หรือ. m เป็น. mm

มีข้อเสียเล็กน้อยสองประการนี้: เสียงดังไม่สามารถวิเคราะห์ซอร์สโค้ด C ++ ได้ รหัส C แปลก ๆ บางตัวไม่รวบรวมภายใต้ C ++


ฉันแค่อยากรู้เล็กน้อยเมื่อคุณรวบรวมทุกอย่างเป็น Objective-C ++ คุณได้รับคำเตือนเกี่ยวกับการใช้ C-style casts และ / หรือ C ++ อื่น ๆ - คำเตือนเฉพาะเกี่ยวกับโค้ด C-style ที่ถูกต้องหรือไม่?
dreamlax

แน่นอนว่าคุณกำลังเขียนโปรแกรมด้วย C ++ ดังนั้นคุณจะต้องทำงานอย่างเหมาะสม แต่ตามกฎทั่วไป C ++ เป็น C ที่ดีกว่า C แม้ว่าคุณจะไม่เคยสร้างคลาสก็ตาม มันจะไม่ปล่อยให้คุณทำอะไรโง่ ๆ และช่วยให้คุณทำสิ่งดีๆได้ (เช่นค่าคงที่และ enums ที่ดีขึ้นเป็นต้น) คุณยังสามารถร่ายได้เหมือนเดิม (เช่น (CFFloat) x)
Peter N Lewis

10

ขั้นตอนที่ 1

สร้างไฟล์ c วัตถุประสงค์ (ไฟล์. m) และเป็นไฟล์ส่วนหัวที่เกี่ยวข้อง

// ไฟล์ส่วนหัว (เราเรียกว่า "ObjCFunc.h")

#ifndef test2_ObjCFunc_h
#define test2_ObjCFunc_h
@interface myClass :NSObject
-(void)hello:(int)num1;
@end
#endif

// ไฟล์ Objective C ที่สอดคล้องกัน (เราเรียกว่า "ObjCFunc.m")

#import <Foundation/Foundation.h>
#include "ObjCFunc.h"
@implementation myClass
//Your objective c code here....
-(void)hello:(int)num1
{
NSLog(@"Hello!!!!!!");
}
@end

ขั้นตอนที่ 2

ตอนนี้เราจะใช้ฟังก์ชัน c ++ เพื่อเรียกฟังก์ชัน c วัตถุประสงค์ที่เราเพิ่งสร้างขึ้น! ดังนั้นเราจะกำหนดไฟล์. mm และไฟล์ส่วนหัวที่เกี่ยวข้อง (ไฟล์ ". mm" จะถูกใช้ที่นี่เพราะเราจะสามารถใช้ทั้ง Objective C และ C ++ coding ในไฟล์)

// ไฟล์ส่วนหัว (เราเรียกว่า "ObjCCall.h")

#ifndef __test2__ObjCCall__
#define __test2__ObjCCall__
#include <stdio.h>
class ObjCCall
{
public:
static void objectiveC_Call(); //We define a static method to call the function directly using the class_name
};
#endif /* defined(__test2__ObjCCall__) */

// ไฟล์ C ++ วัตถุประสงค์ที่สอดคล้องกัน (เราเรียกว่า "ObjCCall.mm")

#include "ObjCCall.h"
#include "ObjCFunc.h"
void ObjCCall::objectiveC_Call()
{
//Objective C code calling.....
myClass *obj=[[myClass alloc]init]; //Allocating the new object for the objective C   class we created
[obj hello:(100)];   //Calling the function we defined
}

ขั้นตอนที่ 3

การเรียกใช้ฟังก์ชัน c ++ (ซึ่งจริงๆแล้วเรียกว่าเมธอด c วัตถุประสงค์)

#ifndef __HELLOWORLD_SCENE_H__
#define __HELLOWORLD_SCENE_H__
#include "cocos2d.h"
#include "ObjCCall.h"
class HelloWorld : public cocos2d::Layer
{
public:
// there's no 'id' in cpp, so we recommend returning the class instance pointer
static cocos2d::Scene* createScene();
// Here's a difference. Method 'init' in cocos2d-x returns bool, instead of returning  'id' in cocos2d-iphone
virtual bool init();
// a selector callback
void menuCloseCallback(cocos2d::Ref* pSender);
void ObCCall();  //definition
// implement the "static create()" method manually
CREATE_FUNC(HelloWorld);
};
#endif // __HELLOWORLD_SCENE_H__

//เรียกครั้งสุดท้าย

#include "HelloWorldScene.h"
#include "ObjCCall.h"
USING_NS_CC;
Scene* HelloWorld::createScene()
{
// 'scene' is an autorelease object
auto scene = Scene::create();
// 'layer' is an autorelease object
auto layer = HelloWorld::create();
// add layer as a child to scene
scene->addChild(layer);
// return the scene
return scene;
}
// on "init" you need to initialize your instance
bool HelloWorld::init()
{
//////////////////////////////
// 1. super init first
if ( !Layer::init() )
{
    return false;
}
Size visibleSize = Director::getInstance()->getVisibleSize();
Vec2 origin = Director::getInstance()->getVisibleOrigin();

/////////////////////////////
// 2. add a menu item with "X" image, which is clicked to quit the program
//    you may modify it.

// add a "close" icon to exit the progress. it's an autorelease object
auto closeItem = MenuItemImage::create(
                                       "CloseNormal.png",
                                       "CloseSelected.png",
                                       CC_CALLBACK_1(HelloWorld::menuCloseCallback,  this));

closeItem->setPosition(Vec2(origin.x + visibleSize.width - closeItem->getContentSize().width/2 ,
                            origin.y + closeItem->getContentSize().height/2));

// create menu, it's an autorelease object
auto menu = Menu::create(closeItem, NULL);
menu->setPosition(Vec2::ZERO);
this->addChild(menu, 1);

/////////////////////////////
// 3. add your codes below...

// add a label shows "Hello World"
// create and initialize a label

auto label = Label::createWithTTF("Hello World", "fonts/Marker Felt.ttf", 24);

// position the label on the center of the screen
label->setPosition(Vec2(origin.x + visibleSize.width/2,
                        origin.y + visibleSize.height - label- >getContentSize().height));
// add the label as a child to this layer
this->addChild(label, 1);
// add "HelloWorld" splash screen"
auto sprite = Sprite::create("HelloWorld.png");
// position the sprite on the center of the screen
sprite->setPosition(Vec2(visibleSize.width/2 + origin.x, visibleSize.height/2 +     origin.y));
// add the sprite as a child to this layer
this->addChild(sprite, 0);
this->ObCCall();   //first call
return true;
}
void HelloWorld::ObCCall()  //Definition
{
ObjCCall::objectiveC_Call();  //Final Call  
}
void HelloWorld::menuCloseCallback(Ref* pSender)
{
#if (CC_TARGET_PLATFORM == CC_PLATFORM_WP8) || (CC_TARGET_PLATFORM ==   CC_PLATFORM_WINRT)
MessageBox("You pressed the close button. Windows Store Apps do not implement a close    button.","Alert");
return;
#endif
Director::getInstance()->end();
#if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
exit(0);
#endif
}

หวังว่าจะได้ผล!


9

คุณต้องทำให้ไฟล์ C ++ ของคุณถือว่าเป็น Objective-C ++ คุณสามารถทำได้ใน xcode โดยเปลี่ยนชื่อ foo.cpp เป็น foo.mm (.mm คือส่วนขยาย obj-c ++) จากนั้นตามที่คนอื่นกล่าวว่าไวยากรณ์การส่งข้อความ obj-c มาตรฐานจะใช้งานได้


1

บางครั้งการเปลี่ยนชื่อ. cpp เป็น. mm ไม่ใช่ความคิดที่ดีโดยเฉพาะเมื่อโปรเจ็กต์ข้ามแพลตฟอร์ม ในกรณีนี้สำหรับโครงการ xcode ฉันเปิดไฟล์โครงการ xcode ผ่าน TextEdit พบสตริงที่เนื้อหาที่สนใจไฟล์ควรเป็นดังนี้:

/* OnlineManager.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = OnlineManager.cpp; sourceTree = "<group>"; };

จากนั้นเปลี่ยนประเภทไฟล์จากsourcecode.cpp.cppเป็นsourcecode.cpp.objcpp

/* OnlineManager.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = **sourcecode.cpp.objcpp**; path = OnlineManager.cpp; sourceTree = "<group>"; };

เทียบเท่ากับการเปลี่ยนชื่อ. cpp เป็น. mm



1

คำตอบของ @ DawidDrozd ข้างต้นนั้นยอดเยี่ยมมาก

ฉันจะเพิ่มหนึ่งจุด คอมไพเลอร์ Clang เวอร์ชันล่าสุดบ่นว่าต้องการ "bridging cast" หากพยายามใช้โค้ดของเขา

สิ่งนี้ดูสมเหตุสมผล: การใช้แทรมโพลีนทำให้เกิดจุดบกพร่องที่อาจเกิดขึ้น: เนื่องจากคลาส Objective-C ถูกนับเป็นข้อมูลอ้างอิงหากเราส่งที่อยู่ของพวกเขาไปรอบ ๆ เป็นโมฆะ * เราเสี่ยงที่จะมีตัวชี้แขวนหากชั้นเรียนเป็นขยะที่รวบรวมในขณะที่การโทรกลับยังอยู่ คล่องแคล่ว.

โซลูชันที่ 1) Cocoa มีฟังก์ชันมาโคร CFBridgingRetain และ CFBridgingRelease ซึ่งน่าจะเพิ่มและลบหนึ่งออกจากจำนวนอ้างอิงของ Objective-C object ดังนั้นเราจึงควรระมัดระวังการโทรกลับหลายครั้งเพื่อปล่อยจำนวนครั้งเท่ากันกับที่เรารักษาไว้

// C++ Module
#include <functional>

void cppFnRequiringCallback(std::function<void(void)> callback) {
        callback();
}

//Objective-C Module
#import "CppFnRequiringCallback.h"

@interface MyObj : NSObject
- (void) callCppFunction;
- (void) myCallbackFn;
@end

void cppTrampoline(const void *caller) {
        id callerObjC = CFBridgingRelease(caller);
        [callerObjC myCallbackFn];
}

@implementation MyObj
- (void) callCppFunction {
        auto callback = [self]() {
                const void *caller = CFBridgingRetain(self);
                cppTrampoline(caller);
        };
        cppFnRequiringCallback(callback);
}

- (void) myCallbackFn {
    NSLog(@"Received callback.");
}
@end

โซลูชันที่ 2) ทางเลือกอื่นคือการใช้การอ้างอิงที่เทียบเท่ากัน (กล่าวคือไม่มีการเปลี่ยนแปลงจำนวนการคงที่) โดยไม่มีความปลอดภัยเพิ่มเติม

ภาษา Objective-C มีคุณสมบัติในการร่าย __bridge ในการทำสิ่งนี้ (CFBridgingRetain และ CFBridgingRelease ดูเหมือนจะเป็น Cocoa wrappers บาง ๆ เหนือโครงสร้างภาษา Objective-C __bridge_retained และ release ตามลำดับ แต่ Cocoa ดูเหมือนจะไม่เทียบเท่ากับ __bridge)

การเปลี่ยนแปลงที่จำเป็น ได้แก่ :

void cppTrampoline(void *caller) {
        id callerObjC = (__bridge id)caller;
        [callerObjC myCallbackFn];
}

- (void) callCppFunction {
        auto callback = [self]() {
                void *caller = (__bridge void *)self;
                cppTrampoline(caller);
        };
        cppFunctionRequiringCallback(callback);
}

ฉันต้องยอมรับว่าฉันค่อนข้างสงสัยว่าโซลูชัน 1 ให้ความปลอดภัยเพิ่มเติมหรือไม่แม้จะมีการเก็บรักษา / เผยแพร่ทั้งหมด ประเด็นหนึ่งคือเรากำลังส่งสำเนาของselfการปิดบัญชีซึ่งอาจล้าสมัย อีกประเด็นหนึ่งคือยังไม่ชัดเจนว่าสิ่งนี้โต้ตอบกับการนับการอ้างอิงอัตโนมัติอย่างไรและคอมไพเลอร์สามารถทราบได้หรือไม่ว่าเกิดอะไรขึ้น ในทางปฏิบัติฉันไม่ได้จัดการสร้างสถานการณ์ที่เวอร์ชันใดเวอร์ชันหนึ่งล้มเหลวในตัวอย่างของเล่นโมดูลเดียวง่ายๆ
QuesterZen

-1

คุณสามารถผสม C ++ กับ Objectiv-C (Objective C ++) ได้ เขียนเมธอด C ++ ในคลาส Objective C ++ ของคุณที่เรียก[context renderbufferStorage:GL_RENDERBUFFER fromDrawable:(CAEAGLLayer*)self.layer];และเรียกใช้จาก C ++ ของคุณ

ฉันยังไม่เคยลองทำมาก่อน แต่ลองดูแล้วแบ่งปันผลลัพธ์กับเรา


2
แต่ปัญหาคือฉันจะเรียกมันได้อย่างไร ... เพราะถ้าฉันรวม "EAGLview.h" ไว้ในคลาส C ++ ของฉันฉันจะได้รับข้อผิดพลาดมากมาย
เยาวชน
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.