You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将C++二维vector转换为C类型以传入SGX enclave?

Convert C++ vector<vector<int>> to C-compatible Type for SGX Enclave

Got it, since SGX's edger8r only supports C types for ECALL/OCALL interfaces, we need to flatten and wrap the 2D vector into a C-style structure that the enclave can handle. Here's a step-by-step example:

1. Define a C-compatible Image Structure

First, create a struct in your EDL file (and mirror it in your C/C++ code if needed) to represent the grayscale image. We'll flatten the 2D vector into a 1D array since C doesn't have built-in dynamic 2D arrays:

// In your enclave.edl file
typedef struct {
    int rows;          // Number of rows in the image
    int cols;          // Number of columns per row
    int* pixel_data;   // Flattened 1D array holding all pixel values
} GrayscaleImage;

2. Convert vector<vector<int>> to the C Structure

In your untrusted C++ code, write a helper function to convert the 2D vector into the GrayscaleImage struct. We'll use malloc for memory allocation since it's C-compatible and easy to free later:

#include <vector>
#include <cstdlib>
#include <cstring>

GrayscaleImage convert_to_c_image(const std::vector<std::vector<int>>& image_pixels) {
    GrayscaleImage c_image{};
    c_image.rows = image_pixels.size();

    // Handle empty image case
    if (c_image.rows == 0) {
        c_image.cols = 0;
        c_image.pixel_data = nullptr;
        return c_image;
    }

    c_image.cols = image_pixels[0].size();
    const size_t total_pixels = static_cast<size_t>(c_image.rows) * c_image.cols;

    // Allocate contiguous memory for flattened pixels
    c_image.pixel_data = static_cast<int*>(malloc(total_pixels * sizeof(int)));
    if (!c_image.pixel_data) {
        // Handle allocation failure
        c_image.rows = 0;
        c_image.cols = 0;
        return c_image;
    }

    // Copy pixel data into the 1D array
    int idx = 0;
    for (const auto& row : image_pixels) {
        // Optional: Validate all rows have the same column count
        if (row.size() != static_cast<size_t>(c_image.cols)) {
            free(c_image.pixel_data);
            c_image.pixel_data = nullptr;
            c_image.rows = 0;
            c_image.cols = 0;
            return c_image;
        }
        memcpy(c_image.pixel_data + idx, row.data(), c_image.cols * sizeof(int));
        idx += c_image.cols;
    }

    return c_image;
}

3. Update EDL for ECALL

When declaring your ECALL in the EDL, you need to tell edger8r how much data to copy for the pixel_data pointer using the [size] attribute. This ensures the enclave receives the full flattened pixel array:

enclave {
    trusted {
        // Declare the ECALL that accepts the image struct
        void process_grayscale_image([in, size=image->rows * image->cols * sizeof(int)] const GrayscaleImage* image);
    };
};

4. Process the Image in the Enclave

In your trusted enclave code, access the pixel data using the flattened array. Calculate the index for a pixel at (row, col) with row * cols + col:

#include "enclave_t.h" // Generated by edger8r

void process_grayscale_image(const GrayscaleImage* image) {
    // Validate input to avoid invalid memory access
    if (!image || image->rows <= 0 || image->cols <= 0 || !image->pixel_data) {
        return;
    }

    // Example: Iterate over all pixels
    for (int row = 0; row < image->rows; ++row) {
        for (int col = 0; col < image->cols; ++col) {
            const int pixel_value = image->pixel_data[static_cast<size_t>(row) * image->cols + col];
            // Add your image processing logic here
        }
    }
}

5. Clean Up Memory

Don't forget to free the allocated memory in your untrusted code after the ECALL completes to avoid leaks:

// After calling the ECALL
GrayscaleImage c_img = convert_to_c_image(ImagePixels);
if (c_img.pixel_data) {
    // Call your ECALL here: sgx_status_t status = ecall_process_grayscale_image(enclave_id, &ret_val, &c_img);
    free(c_img.pixel_data);
}

Key Notes

  • Input Validation: Always check for empty images, mismatched row lengths, and null pointers to prevent crashes in the enclave.
  • Memory Safety: The [in] attribute tells edger8r to copy data from untrusted memory into the enclave's protected memory, ensuring isolation.
  • Flexible Alternative: If you prefer, use a flexible array member in the struct (e.g., int pixel_data[];), but you'll need to allocate the struct plus pixel data in a single malloc call.

内容的提问来源于stack exchange,提问作者asonnino

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 03:49:19