C++ 我需要帮助混合C++;代码与目标C代码
我正在用XCode为Blackmagic Design AV设备编写一个设备驱动程序,在将BMD的SyncController类从其缩写示例代码(如下)中包含到我的纯Objective-C项目中时遇到了问题C++ 我需要帮助混合C++;代码与目标C代码,c++,objective-c,xcode,class-extensions,C++,Objective C,Xcode,Class Extensions,我正在用XCode为Blackmagic Design AV设备编写一个设备驱动程序,在将BMD的SyncController类从其缩写示例代码(如下)中包含到我的纯Objective-C项目中时遇到了问题 他们的DekLink kp.h文件中有丰富的C++代码,所以当我尝试将这个头文件包含在Abjule- C类中时,编译器中的编译器扼要地包含:未知类型名称“类”;你是说“课堂”吗 我已经尝试将C++位捆绑成Obj-C类扩展,但没有太大的成功。我从来没有做过任何C++编程(而且从来没有使用Obj
他们的DekLink kp.h文件中有丰富的C++代码,所以当我尝试将这个头文件包含在Abjule- C类中时,编译器中的编译器扼要地包含:未知类型名称“类”;你是说“课堂”吗
我已经尝试将C++位捆绑成Obj-C类扩展,但没有太大的成功。我从来没有做过任何C++编程(而且从来没有使用Obj-C类扩展),所以这是我的新领域。
我不确定是否需要为我的SycCube对象创建一个附加包装类,或者我是否可以在这个上做一个类扩展,并将C++位混到.mm文件中。 我希望能够在Objective-C类中执行
#include“SyncController.h”
(或其包装器),而无需编译器阻塞
在此过程中提供的任何帮助都将不胜感激。
首先,这是我当前的SyncController.h文件:
#import <Cocoa/Cocoa.h>
#import "DeckLinkAPI.h" // this is rich in C++ code
class PlaybackDelegate;
@interface SyncController : NSObject {
PlaybackDelegate* playerDelegate;
IDeckLink* deckLink;
IDeckLinkOutput* deckLinkOutput;
}
- (void)scheduleNextFrame:(BOOL)prerolling;
- (void)writeNextAudioSamples;
@end
class PlaybackDelegate : public IDeckLinkVideoOutputCallback, public IDeckLinkAudioOutputCallback
{
SyncController* mController;
IDeckLinkOutput* mDeckLinkOutput;
public:
PlaybackDelegate (SyncController* owner, IDeckLinkOutput* deckLinkOutput);
// IUnknown needs only a dummy implementation
virtual HRESULT QueryInterface (REFIID iid, LPVOID *ppv) {return E_NOINTERFACE;}
virtual ULONG AddRef () {return 1;}
virtual ULONG Release () {return 1;}
virtual HRESULT ScheduledFrameCompleted (IDeckLinkVideoFrame* completedFrame, BMDOutputFrameCompletionResult result);
virtual HRESULT ScheduledPlaybackHasStopped ();
virtual HRESULT RenderAudioSamples (bool preroll);
};
void ScheduleNextVideoFrame (void);
#导入
“导入”DekLink(.h)/ /这是丰富的C++代码
类播放代理;
@接口同步控制器:NSObject{
PlaybackDelegate*playerDelegate;
IDeckLink*deckLink;
IDeckLinkOutput*deckLinkOutput;
}
-(无效)scheduleNextFrame:(BOOL)预滚动;
-(无效)书面额外音频样本;
@结束
类PlaybackDelegate:public IDeckLinkVideoOutputCallback、public IDeckLinkAudioOutputCallback
{
同步控制器*mController;
IDeckLinkOutput*mDeckLinkOutput;
公众:
PlaybackDelegate(SyncController*所有者,IDeckLinkOutput*deckLinkOutput);
//IUnknown只需要一个虚拟实现
虚拟HRESULT查询接口(refid iid,LPVOID*ppv){return E_NOINTERFACE;}
虚拟ULONG AddRef(){return 1;}
虚拟ULONG释放(){return 1;}
虚拟HRESULT ScheduledFrameCompleted(IDeckLinkVideoFrame*completedFrame,BMDOutputFrameCompletionResult);
虚拟HRESULT ScheduledPlaybackHasstop();
虚拟HRESULT渲染样本(布尔预滚);
};
void ScheduleNextVideoFrame(void);
接下来,这里是我的(简化的)SyncController.mm文件:
#import <CoreFoundation/CFString.h>
#import "SyncController.h"
@implementation SyncController
- (instancetype)init
{
self = [super init];
return self;
}
- (void)dealloc
{
}
- (void)scheduleNextFrame:(BOOL)prerolling
{
}
- (void)writeNextAudioSamples
{
}
@end
PlaybackDelegate::PlaybackDelegate (SyncController* owner, IDeckLinkOutput* deckLinkOutput)
{
mController = owner;
mDeckLinkOutput = deckLinkOutput;
}
HRESULT PlaybackDelegate::ScheduledFrameCompleted (IDeckLinkVideoFrame* completedFrame, BMDOutputFrameCompletionResult result)
{
[mController scheduleNextFrame:NO];
return S_OK;
}
HRESULT PlaybackDelegate::ScheduledPlaybackHasStopped ()
{
return S_OK;
}
HRESULT PlaybackDelegate::RenderAudioSamples (bool preroll)
{
[mController writeNextAudioSamples];
if (preroll)
mDeckLinkOutput->StartScheduledPlayback(0, 100, 1.0);
return S_OK;
}
#导入
#导入“SyncController.h”
@实现同步控制器
-(instancetype)初始化
{
self=[super init];
回归自我;
}
-(无效)解除锁定
{
}
-(无效)scheduleNextFrame:(BOOL)预滚动
{
}
-(无效)writeNextAudioSamples
{
}
@结束
PlaybackDelegate::PlaybackDelegate(SyncController*所有者,IDeckLinkOutput*deckLinkOutput)
{
mController=所有者;
mDeckLinkOutput=deckLinkOutput;
}
HRESULT PlaybackDelegate::ScheduledFrameCompleted(IDeckLinkVideoFrame*completedFrame,BMDoutFrameCompletionResult)
{
[mController ScheduleNext帧:否];
返回S_OK;
}
HRESULT PlaybackDelegate::ScheduledPlaybackHassToped()
{
返回S_OK;
}
HRESULT PlaybackDelegate::RenderAudioSamples(布尔预滚)
{
[mController writeNextAudioSamples];
if(预滚)
mDeckLinkOutput->StartScheduledPlayback(01001.0);
返回S_OK;
}
不是一个完整的答案,但是错误如下:
未知类型名称“类”;你是说“课堂”吗
是ObjuleC++的经典问题,其中<强> Objy-C实现文件看到C++头文件>/P> 我只能提供如何避免它的建议,因为您没有发布完整的构建输出
- 不要把C++头放在预编译的头上。
#import <vector>
@implementation MyObjCppClass {
std::vector<int> _stuff;
}
- (id)init {
...
}
@end
#导入
@类的实现{
std::vector\u stuff;
}
-(id)init{
...
}
@结束
<> >如果你是Objy-C和ObjuleC++,那么你可能会发现你需要提供Objy-C包装器到C++类(从外部看为Objtovi-C,但实际上是用ObjuleC++实现)。
#import <Cocoa/Cocoa.h>
#if __cplusplus
#import "DeckLinkAPI.h" // this is rich in C++ code
#endif // __cplusplus
@interface SyncController : NSObject {
void* playerDelegate; // should be cast as C++ PlaybackDelegate class.
...
}
@end
#if __cplusplus
class PlaybackDelegate : public IDeckLinkVideoOutputCallback, public IDeckLinkAudioOutputCallback
{
...
};
#endif // __cplusplus
在Objective-C++代码中
// initialize
syncController.playerDelegate = new PlaybackDelegate();
// use the pointer
PlaybackDelegate *playbackDelegate = (PlaybackDelegate *)syncController.playerDelegate;
我曾试图将C++位捆绑成Obj-C类扩展,如这里所指出的,但没有太大的成功。 如果您的目标是64位,那么类扩展方法应该相当简单
下面的代码与您所发布的代码相当,但将所有C++声明移到单独的标题:
SyncController.h:#import <Cocoa/Cocoa.h>
@interface SyncController : NSObject
- (void)scheduleNextFrame:(BOOL)prerolling;
- (void)writeNextAudioSamples;
@end
SyncController.mm
#import "SyncController_CPP.h"
@implementation SyncController
...
@end
PlaybackDelegate::PlaybackDelegate (SyncController* owner, IDeckLinkOutput* deckLinkOutput)
{
mController = owner;
mDeckLinkOutput = deckLinkOutput;
}
// etc..
需要访问SyncController
的任何其他ObjC类将导入“SyncController.h”。任何其他ObjC++类都可以导入“SyncController.h”或“SyncController\u CPP.h”初始化
syncController.playerDelegate = new PlaybackDelegate();
// use the pointer
PlaybackDelegate *playbackDelegate = (PlaybackDelegate *)syncController.playerDelegate
错误消息是什么?正如在文章中所指出的,我遇到了一个关于“未知类型名'class'的问题;您是指'class'?“您使用的是旧版本的Xcode或gcc,还是针对32位OS X?”?这将影响您如何使用类extensio
#import "SyncController_CPP.h"
@implementation SyncController
...
@end
PlaybackDelegate::PlaybackDelegate (SyncController* owner, IDeckLinkOutput* deckLinkOutput)
{
mController = owner;
mDeckLinkOutput = deckLinkOutput;
}
// etc..
syncController.playerDelegate = new PlaybackDelegate();
// use the pointer
PlaybackDelegate *playbackDelegate = (PlaybackDelegate *)syncController.playerDelegate