2

XCode で Blackmagic Design AV デバイス用のデバイス ドライバーを作成していますが、BMD の SyncController クラスを簡略化されたサンプル コード (以下) から純粋な Objective-C プロジェクトに含めるのに問題があります。

彼らの DecklinkAPI.h ファイルには C++ コードが豊富に含まれているため、このヘッダー ファイルをそのまま Objective-C クラスにインクルードしようとすると、コンパイラは API インクルードの奥深くでチョークを実行します。「クラス」のことですか?

hereに記載されているように、C++ ビットを Obj-C クラス拡張にバンドルしようとしましたが、あまり成功しませんでした。私は C++ プログラミングをしたことがない (そして Obj-C クラス拡張機能を使用したことがない) ので、これは私にとって新しい領域です。

SyncController オブジェクト用に追加のラッパー クラスを作成する必要があるかどうか、またはこのオブジェクトでクラス拡張を行って C++ ビットを .mm ファイルにシャッフルできるかどうかはわかりません。

#include "SyncController.h"コンパイラがチョークすることなく、Objective-C クラスでa (またはそのラッパー) を実行できるようにしたいと考えています。

そのための支援をいただければ幸いです。

まず、現在の 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);

次に、これが私の (単純化された) 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;
}
4

5 に答える 5

1

を使用し#if __cplusplusます。

例えば、

#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 および Objective-C++ で使用できます。ただし、ヘッダーの SyncController Objective-C クラス宣言で C++ クラス シグネチャを使用することはできません。適切な型キャストvoid *の代わりに使用します。PlaybackDelegate *

また、使用void *すると、ヘッダー内の C++ が不要になります。

#import <Cocoa/Cocoa.h>

@interface SyncController : NSObject {
    void* playerDelegate; // should be cast as C++ PlaybackDelegate class.
    ...
}
@end

Objective-C++ コードでは、

// initialize
syncController.playerDelegate = new PlaybackDelegate();

// use the pointer
PlaybackDelegate *playbackDelegate = (PlaybackDelegate *)syncController.playerDelegate;
于 2014-07-11T21:07:20.107 に答える