Skip to content

Commit 1681b9f

Browse files
committed
Add static assert for enums between C and C++ interface
1 parent a5d2076 commit 1681b9f

4 files changed

Lines changed: 134 additions & 8 deletions

File tree

include/ccap_c.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,10 @@ typedef enum {
3939
CCAP_PIXEL_FORMAT_NV12F = CCAP_PIXEL_FORMAT_NV12 | (1 << 17),
4040
CCAP_PIXEL_FORMAT_I420 = (1 << 2) | (1 << 16),
4141
CCAP_PIXEL_FORMAT_I420F = CCAP_PIXEL_FORMAT_I420 | (1 << 17),
42+
CCAP_PIXEL_FORMAT_YUYV = (1 << 3) | (1 << 16),
43+
CCAP_PIXEL_FORMAT_YUYV_F = CCAP_PIXEL_FORMAT_YUYV | (1 << 17),
44+
CCAP_PIXEL_FORMAT_UYVY = (1 << 4) | (1 << 16),
45+
CCAP_PIXEL_FORMAT_UYVY_F = CCAP_PIXEL_FORMAT_UYVY | (1 << 17),
4246
CCAP_PIXEL_FORMAT_RGB24 = (1 << 3) | (1 << 18),
4347
CCAP_PIXEL_FORMAT_BGR24 = (1 << 4) | (1 << 18),
4448
CCAP_PIXEL_FORMAT_RGBA32 = CCAP_PIXEL_FORMAT_RGB24 | (1 << 19),

src/ccap_c.cpp

Lines changed: 101 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,10 @@
77
*/
88

99
#include "ccap_c.h"
10+
#include "ccap_utils_c.h"
1011

1112
#include "ccap.h"
13+
#include "ccap_utils.h"
1214

1315
#include <cmath>
1416
#include <cstring>
@@ -367,23 +369,23 @@ void ccap_provider_set_max_cache_frame_size(CcapProvider* provider, uint32_t siz
367369
bool ccap_set_error_callback(CcapErrorCallback callback, void* userData) {
368370
try {
369371
std::lock_guard<std::mutex> lock(g_cErrorCallbackMutex);
370-
372+
371373
if (callback) {
372374
g_cGlobalErrorCallbackWrapper = std::make_shared<ErrorCallbackWrapper>(callback, userData);
373-
375+
374376
ccap::setErrorCallback([](ccap::ErrorCode errorCode, const std::string& description) {
375377
std::lock_guard<std::mutex> lock(g_cErrorCallbackMutex);
376378
if (g_cGlobalErrorCallbackWrapper && g_cGlobalErrorCallbackWrapper->callback) {
377-
g_cGlobalErrorCallbackWrapper->callback(convert_error_code_to_c(errorCode),
378-
description.c_str(),
379+
g_cGlobalErrorCallbackWrapper->callback(convert_error_code_to_c(errorCode),
380+
description.c_str(),
379381
g_cGlobalErrorCallbackWrapper->userData);
380382
}
381383
});
382384
} else {
383385
g_cGlobalErrorCallbackWrapper = nullptr;
384386
ccap::setErrorCallback(nullptr);
385387
}
386-
388+
387389
return true;
388390
} catch (...) {
389391
return false;
@@ -413,4 +415,97 @@ bool ccap_pixel_format_is_yuv(CcapPixelFormat format) {
413415
return (static_cast<uint32_t>(format) & YUV_COLOR_BIT) != 0;
414416
}
415417

416-
} // extern "C"
418+
} // extern "C"
419+
420+
// Static assertions to ensure C and C++ enum values are consistent
421+
// This prevents type casting issues when passing enum values between C and C++ layers
422+
423+
// PixelFormat enum consistency checks
424+
static_assert(static_cast<uint32_t>(CCAP_PIXEL_FORMAT_UNKNOWN) == static_cast<uint32_t>(ccap::PixelFormat::Unknown),
425+
"C and C++ PixelFormat::Unknown values must match");
426+
static_assert(static_cast<uint32_t>(CCAP_PIXEL_FORMAT_NV12) == static_cast<uint32_t>(ccap::PixelFormat::NV12),
427+
"C and C++ PixelFormat::NV12 values must match");
428+
static_assert(static_cast<uint32_t>(CCAP_PIXEL_FORMAT_NV12F) == static_cast<uint32_t>(ccap::PixelFormat::NV12f),
429+
"C and C++ PixelFormat::NV12f values must match");
430+
static_assert(static_cast<uint32_t>(CCAP_PIXEL_FORMAT_I420) == static_cast<uint32_t>(ccap::PixelFormat::I420),
431+
"C and C++ PixelFormat::I420 values must match");
432+
static_assert(static_cast<uint32_t>(CCAP_PIXEL_FORMAT_I420F) == static_cast<uint32_t>(ccap::PixelFormat::I420f),
433+
"C and C++ PixelFormat::I420f values must match");
434+
static_assert(static_cast<uint32_t>(CCAP_PIXEL_FORMAT_YUYV) == static_cast<uint32_t>(ccap::PixelFormat::YUYV),
435+
"C and C++ PixelFormat::YUYV values must match");
436+
static_assert(static_cast<uint32_t>(CCAP_PIXEL_FORMAT_YUYV_F) == static_cast<uint32_t>(ccap::PixelFormat::YUYVf),
437+
"C and C++ PixelFormat::YUYVf values must match");
438+
static_assert(static_cast<uint32_t>(CCAP_PIXEL_FORMAT_UYVY) == static_cast<uint32_t>(ccap::PixelFormat::UYVY),
439+
"C and C++ PixelFormat::UYVY values must match");
440+
static_assert(static_cast<uint32_t>(CCAP_PIXEL_FORMAT_UYVY_F) == static_cast<uint32_t>(ccap::PixelFormat::UYVYf),
441+
"C and C++ PixelFormat::UYVYf values must match");
442+
static_assert(static_cast<uint32_t>(CCAP_PIXEL_FORMAT_RGB24) == static_cast<uint32_t>(ccap::PixelFormat::RGB24),
443+
"C and C++ PixelFormat::RGB24 values must match");
444+
static_assert(static_cast<uint32_t>(CCAP_PIXEL_FORMAT_BGR24) == static_cast<uint32_t>(ccap::PixelFormat::BGR24),
445+
"C and C++ PixelFormat::BGR24 values must match");
446+
static_assert(static_cast<uint32_t>(CCAP_PIXEL_FORMAT_RGBA32) == static_cast<uint32_t>(ccap::PixelFormat::RGBA32),
447+
"C and C++ PixelFormat::RGBA32 values must match");
448+
static_assert(static_cast<uint32_t>(CCAP_PIXEL_FORMAT_BGRA32) == static_cast<uint32_t>(ccap::PixelFormat::BGRA32),
449+
"C and C++ PixelFormat::BGRA32 values must match");
450+
451+
// FrameOrientation enum consistency checks
452+
static_assert(static_cast<uint32_t>(CCAP_FRAME_ORIENTATION_TOP_TO_BOTTOM) == static_cast<uint32_t>(ccap::FrameOrientation::TopToBottom),
453+
"C and C++ FrameOrientation::TopToBottom values must match");
454+
static_assert(static_cast<uint32_t>(CCAP_FRAME_ORIENTATION_BOTTOM_TO_TOP) == static_cast<uint32_t>(ccap::FrameOrientation::BottomToTop),
455+
"C and C++ FrameOrientation::BottomToTop values must match");
456+
457+
// PropertyName enum consistency checks
458+
static_assert(static_cast<uint32_t>(CCAP_PROPERTY_WIDTH) == static_cast<uint32_t>(ccap::PropertyName::Width),
459+
"C and C++ PropertyName::Width values must match");
460+
static_assert(static_cast<uint32_t>(CCAP_PROPERTY_HEIGHT) == static_cast<uint32_t>(ccap::PropertyName::Height),
461+
"C and C++ PropertyName::Height values must match");
462+
static_assert(static_cast<uint32_t>(CCAP_PROPERTY_FRAME_RATE) == static_cast<uint32_t>(ccap::PropertyName::FrameRate),
463+
"C and C++ PropertyName::FrameRate values must match");
464+
static_assert(static_cast<uint32_t>(CCAP_PROPERTY_PIXEL_FORMAT_INTERNAL) == static_cast<uint32_t>(ccap::PropertyName::PixelFormatInternal),
465+
"C and C++ PropertyName::PixelFormatInternal values must match");
466+
static_assert(static_cast<uint32_t>(CCAP_PROPERTY_PIXEL_FORMAT_OUTPUT) == static_cast<uint32_t>(ccap::PropertyName::PixelFormatOutput),
467+
"C and C++ PropertyName::PixelFormatOutput values must match");
468+
static_assert(static_cast<uint32_t>(CCAP_PROPERTY_FRAME_ORIENTATION) == static_cast<uint32_t>(ccap::PropertyName::FrameOrientation),
469+
"C and C++ PropertyName::FrameOrientation values must match");
470+
471+
// ErrorCode enum consistency checks
472+
static_assert(static_cast<uint32_t>(CCAP_ERROR_NONE) == static_cast<uint32_t>(ccap::ErrorCode::None),
473+
"C and C++ ErrorCode::None values must match");
474+
static_assert(static_cast<uint32_t>(CCAP_ERROR_NO_DEVICE_FOUND) == static_cast<uint32_t>(ccap::ErrorCode::NoDeviceFound),
475+
"C and C++ ErrorCode::NoDeviceFound values must match");
476+
static_assert(static_cast<uint32_t>(CCAP_ERROR_INVALID_DEVICE) == static_cast<uint32_t>(ccap::ErrorCode::InvalidDevice),
477+
"C and C++ ErrorCode::InvalidDevice values must match");
478+
static_assert(static_cast<uint32_t>(CCAP_ERROR_DEVICE_OPEN_FAILED) == static_cast<uint32_t>(ccap::ErrorCode::DeviceOpenFailed),
479+
"C and C++ ErrorCode::DeviceOpenFailed values must match");
480+
static_assert(static_cast<uint32_t>(CCAP_ERROR_DEVICE_START_FAILED) == static_cast<uint32_t>(ccap::ErrorCode::DeviceStartFailed),
481+
"C and C++ ErrorCode::DeviceStartFailed values must match");
482+
static_assert(static_cast<uint32_t>(CCAP_ERROR_DEVICE_STOP_FAILED) == static_cast<uint32_t>(ccap::ErrorCode::DeviceStopFailed),
483+
"C and C++ ErrorCode::DeviceStopFailed values must match");
484+
static_assert(static_cast<uint32_t>(CCAP_ERROR_UNSUPPORTED_RESOLUTION) == static_cast<uint32_t>(ccap::ErrorCode::UnsupportedResolution),
485+
"C and C++ ErrorCode::UnsupportedResolution values must match");
486+
static_assert(static_cast<uint32_t>(CCAP_ERROR_UNSUPPORTED_PIXEL_FORMAT) == static_cast<uint32_t>(ccap::ErrorCode::UnsupportedPixelFormat),
487+
"C and C++ ErrorCode::UnsupportedPixelFormat values must match");
488+
static_assert(static_cast<uint32_t>(CCAP_ERROR_FRAME_RATE_SET_FAILED) == static_cast<uint32_t>(ccap::ErrorCode::FrameRateSetFailed),
489+
"C and C++ ErrorCode::FrameRateSetFailed values must match");
490+
static_assert(static_cast<uint32_t>(CCAP_ERROR_PROPERTY_SET_FAILED) == static_cast<uint32_t>(ccap::ErrorCode::PropertySetFailed),
491+
"C and C++ ErrorCode::PropertySetFailed values must match");
492+
static_assert(static_cast<uint32_t>(CCAP_ERROR_FRAME_CAPTURE_TIMEOUT) == static_cast<uint32_t>(ccap::ErrorCode::FrameCaptureTimeout),
493+
"C and C++ ErrorCode::FrameCaptureTimeout values must match");
494+
static_assert(static_cast<uint32_t>(CCAP_ERROR_FRAME_CAPTURE_FAILED) == static_cast<uint32_t>(ccap::ErrorCode::FrameCaptureFailed),
495+
"C and C++ ErrorCode::FrameCaptureFailed values must match");
496+
static_assert(static_cast<uint32_t>(CCAP_ERROR_MEMORY_ALLOCATION_FAILED) == static_cast<uint32_t>(ccap::ErrorCode::MemoryAllocationFailed),
497+
"C and C++ ErrorCode::MemoryAllocationFailed values must match");
498+
static_assert(static_cast<uint32_t>(CCAP_ERROR_INTERNAL_ERROR) == static_cast<uint32_t>(ccap::ErrorCode::InternalError),
499+
"C and C++ ErrorCode::InternalError values must match");
500+
501+
// LogLevel enum consistency checks
502+
static_assert(static_cast<uint32_t>(CCAP_LOG_LEVEL_NONE) == static_cast<uint32_t>(ccap::LogLevel::None),
503+
"C and C++ LogLevel::None values must match");
504+
static_assert(static_cast<uint32_t>(CCAP_LOG_LEVEL_ERROR) == static_cast<uint32_t>(ccap::LogLevel::Error),
505+
"C and C++ LogLevel::Error values must match");
506+
static_assert(static_cast<uint32_t>(CCAP_LOG_LEVEL_WARNING) == static_cast<uint32_t>(ccap::LogLevel::Warning),
507+
"C and C++ LogLevel::Warning values must match");
508+
static_assert(static_cast<uint32_t>(CCAP_LOG_LEVEL_INFO) == static_cast<uint32_t>(ccap::LogLevel::Info),
509+
"C and C++ LogLevel::Info values must match");
510+
static_assert(static_cast<uint32_t>(CCAP_LOG_LEVEL_VERBOSE) == static_cast<uint32_t>(ccap::LogLevel::Verbose),
511+
"C and C++ LogLevel::Verbose values must match");

src/ccap_convert_c.cpp

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,33 @@
1212

1313
#include <cstring>
1414

15+
// Static assertions to ensure C and C++ convert enum values are consistent
16+
// This prevents type casting issues when passing enum values between C and C++ layers
17+
18+
// ConvertBackend enum consistency checks
19+
static_assert(static_cast<uint32_t>(CCAP_CONVERT_BACKEND_AUTO) == static_cast<uint32_t>(ccap::ConvertBackend::AUTO),
20+
"C and C++ ConvertBackend::AUTO values must match");
21+
static_assert(static_cast<uint32_t>(CCAP_CONVERT_BACKEND_CPU) == static_cast<uint32_t>(ccap::ConvertBackend::CPU),
22+
"C and C++ ConvertBackend::CPU values must match");
23+
static_assert(static_cast<uint32_t>(CCAP_CONVERT_BACKEND_AVX2) == static_cast<uint32_t>(ccap::ConvertBackend::AVX2),
24+
"C and C++ ConvertBackend::AVX2 values must match");
25+
static_assert(static_cast<uint32_t>(CCAP_CONVERT_BACKEND_APPLE_ACCELERATE) == static_cast<uint32_t>(ccap::ConvertBackend::AppleAccelerate),
26+
"C and C++ ConvertBackend::AppleAccelerate values must match");
27+
static_assert(static_cast<uint32_t>(CCAP_CONVERT_BACKEND_NEON) == static_cast<uint32_t>(ccap::ConvertBackend::NEON),
28+
"C and C++ ConvertBackend::NEON values must match");
29+
30+
// ConvertFlag enum consistency checks
31+
static_assert(static_cast<uint32_t>(CCAP_CONVERT_FLAG_BT601) == static_cast<uint32_t>(ccap::ConvertFlag::BT601),
32+
"C and C++ ConvertFlag::BT601 values must match");
33+
static_assert(static_cast<uint32_t>(CCAP_CONVERT_FLAG_BT709) == static_cast<uint32_t>(ccap::ConvertFlag::BT709),
34+
"C and C++ ConvertFlag::BT709 values must match");
35+
static_assert(static_cast<uint32_t>(CCAP_CONVERT_FLAG_FULL_RANGE) == static_cast<uint32_t>(ccap::ConvertFlag::FullRange),
36+
"C and C++ ConvertFlag::FullRange values must match");
37+
static_assert(static_cast<uint32_t>(CCAP_CONVERT_FLAG_VIDEO_RANGE) == static_cast<uint32_t>(ccap::ConvertFlag::VideoRange),
38+
"C and C++ ConvertFlag::VideoRange values must match");
39+
static_assert(static_cast<uint32_t>(CCAP_CONVERT_FLAG_DEFAULT) == static_cast<uint32_t>(ccap::ConvertFlag::Default),
40+
"C and C++ ConvertFlag::Default values must match");
41+
1542
extern "C" {
1643

1744
/* ========== Conversion Backend Management ========== */
@@ -361,4 +388,4 @@ void ccap_convert_uyvy_to_rgba32(const uint8_t* src, int src_stride,
361388
ccap::uyvyToRgba32(src, src_stride, dst, dst_stride, width, height, convertFlags(flag));
362389
}
363390

364-
} // extern "C"
391+
} // extern "C"

src/ccap_utils_c.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -167,4 +167,4 @@ void ccap_set_log_level(CcapLogLevel level) {
167167
ccap::setLogLevel(cppLogLevel);
168168
}
169169

170-
} // extern "C"
170+
} // extern "C"

0 commit comments

Comments
 (0)