通过FireMonKey/C 在OS X中的地址com

Address COM in OS X via FireMonkey/C++

本文关键字:地址 com OS FireMonKey 通过      更新时间:2023-10-16

可用于Windows和OS X的基于COM的Blackmagic Decklink API。我希望在OS X中解决它,但在C 中使用FiremonKey(FMX)。问题在于他们的样本代码*是为可可编写的,我不知道如何为firemonkey重写它。有人对此有任何经验吗?

或,是否有一种通用方式可以在FiremonKey/OS X?

中解决具有COM接口的库

根据请求,这是可可代码的一部分。

void    InitDeckLinkAPI (void)
{
    CFURLRef        bundleURL;
    bundleURL = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, CFSTR(kDeckLinkAPI_BundlePath), kCFURLPOSIXPathStyle, true);
    if (bundleURL != NULL)
    {
        gDeckLinkAPIBundleRef = CFBundleCreate(kCFAllocatorDefault, bundleURL);
        if (gDeckLinkAPIBundleRef != NULL)
        {
            gCreateIteratorFunc = (CreateIteratorFunc)CFBundleGetFunctionPointerForName(gDeckLinkAPIBundleRef, CFSTR("CreateDeckLinkIteratorInstance_0002"));
            gCreateAPIInformationFunc = (CreateAPIInformationFunc)CFBundleGetFunctionPointerForName(gDeckLinkAPIBundleRef, CFSTR("CreateDeckLinkAPIInformationInstance_0001"));
            gCreateOpenGLPreviewFunc = (CreateOpenGLScreenPreviewHelperFunc)CFBundleGetFunctionPointerForName(gDeckLinkAPIBundleRef, CFSTR("CreateOpenGLScreenPreviewHelper_0001"));
            gCreateCocoaPreviewFunc = (CreateCocoaScreenPreviewFunc)CFBundleGetFunctionPointerForName(gDeckLinkAPIBundleRef, CFSTR("CreateCocoaScreenPreview_0001"));
            gCreateVideoConversionFunc = (CreateVideoConversionInstanceFunc)CFBundleGetFunctionPointerForName(gDeckLinkAPIBundleRef, CFSTR("CreateVideoConversionInstance_0001"));
        }
        CFRelease(bundleURL);
    }
}
bool        IsDeckLinkAPIPresent (void)
{
    // If the DeckLink API bundle was successfully loaded, return this knowledge to the caller
    if (gDeckLinkAPIBundleRef != NULL)
        return true;
    return false;
}
IDeckLinkIterator*      CreateDeckLinkIteratorInstance (void)
{
    pthread_once(&gDeckLinkOnceControl, InitDeckLinkAPI);
    if (gCreateIteratorFunc == NULL)
        return NULL;
    return gCreateIteratorFunc();
}

*在此处包括的时间太长,但您可以在此处下载。

在没有本机com支持的平台上(例如OS X),应提供c入口点以访问接口,在Decklink API中,有这样的工厂方法:

IDeckLinkIterator *deckLinkIterator = CreateDeckLinkIteratorInstance();

因此,您可以简单地使用C 构建器中的DeckLink API。但是存在问题,C 构建器已定义了一些com类型,例如sysmac.h中的iunknown(由system.hpp包括),如果您的项目包括system.hpp,则在cfplugincom.h中定义了与相同类型的冲突。例如所有FireMonkey项目编译器都会显示一个错误:

[bccosx Error] sysmac.h(287): E2238 Multiple declaration for 'IUnknown'

有一个名为 DeckControl 在Decklink API的样品目录中的样本,这是一个控制台程序,您可以通过C 构建器对其进行编译:

  1. 创建一个控制台项目并将Main.CPP指定为项目来源。
  2. 选择"无"作为目标框架
  3. 添加" OSX"平台

该项目是成功的。

和FMX项目(使用System.HPP)呢?
创建一个包装单元(例如BCB_DECK)将所需的API放入其中。请注意,在单位标头中不包括" decklinkapi.h",这会导致上述相同的问题,但将其放入CPP(BCB_DECK.CPP)中,例如:

bcb_deck.cpp:

void* createDeckLinkIteratorInstance() // use camel case to prevent conflict
{
    return (void*) CreateDeckLinkIteratorInstance();
}
bool deckLinkIteratorNext(void *hDeckLinkIterator, void *hDeckLink)
{
    IDeckLinkIterator *deckLinkIterator = (IDeckLinkIterator*) hDeckLinkIterator;
    IDeckLink *deckLink = (IDeckLink*) hDeckLink;
    return deckLinkIterator->Next(&deckLink) == S_OK;
}

用法:

#include "bcb_deck.h"
void *hDeckLinkIterator, *hDeckLink;
hDeckLinkIterator = createDeckLinkIteratorInstance();
if (hDeckLinkIterator)
{
    // Enumerate all cards in this system
    while (deckLinkIteratorNext(hDeckLinkIterator, hDeckLink))
    {
        // ...
    }
}