API-интерфейс Blackmagic DeckLink на основе COM доступен как для Windows, так и для OS X. Я хотел бы обратиться к нему в OS X, но с использованием FireMonkey (FMX) в C ++. Проблема в том, что их пример кода * написан для Какао, и я понятия не имею, как переписать его для FireMonkey. Есть ли у кого-нибудь опыт с этим, возможно ли это вообще.
Или есть ли общий способ, которым библиотеки с интерфейсом COM могут быть адресованы в FireMonkey / OS X?
Вот часть кода для Какао, по запросу.
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();
Таким образом, вы можете просто использовать DeckLink API в C ++ Builder. Но есть проблема, C ++ Builder определил некоторые типы COM, такие как IUnknown в sysmac.h (входит в состав System.hpp), конфликты с такими же типами были определены в CFPluginCOM.h, если ваш проект включает System.hpp например, во всех проектах firemonkey компилятор отображает ошибку:
[bccosx Error] sysmac.h(287): E2238 Multiple declaration for 'IUnknown'
Есть образец с именем DeckControl в каталоге примеров API DeckLink, который является консольной программой, и вы можете скомпилировать его с помощью C ++ Builder:
Проект составлен успешно.
А что насчет проекта 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))
{
// ...
}
}
Других решений пока нет …