IncompatibleTypes for Complex Data and Cross Language (cxx to python) #1029
-
As this is a different topic from the previous discussion, please let me post here for future reference if applicable. The types below are suitable for C++ to C++ or Python to Python publish-subscribe patterns. However, I couldn't let them work for cpp -> python or vice versa. Unless I'm missing something, iox::vector and Python (ctypes.c_uint8 * DATA_SIZE) result in the type mismatch error. iceoryx2_ffi_python.PublishSubscribeOpenOrCreateError: PublishSubscribeOpenError(IncompatibleTypes) Please let me know if there is Python specific correspondance for
other than
FYI, in my usecase, I couln't use due to the Windows OS stack limit. #1025
CXX Type
Python Type
Work around?Not sure if dynamic data would work with different languages. Yet even if so, it looks a literal foor loop which may be a bottle neck for larger data.
at least any method to be used with memcpy? |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments 1 reply
-
@ElliotHYLee We are currently working on memory layout compatible data types and the first implementation will come with a Rust <-> C++ string and vector. The python part will come later as soon as we have secured some funding for it. So for now, you can use this: Pythonclass GenericHeader(ctypes.Structure):
_fields_ = [
("frame_id", ctypes.c_uint32),
("timestamp", ctypes.c_uint64),
]
@staticmethod
def type_name() -> str:
return "GenericHeader"
class ImageData720p(ctypes.Structure):
_fields_ = [
("WIDTH", ctypes.c_uint16),
...
("image_data", ctypes.c_uint8 * 1280 * 720 * 4), # Fixed-size RGBA image array
]
@staticmethod
def type_name() -> str:
return "ImageData720p" C++struct GenericHeader {
static constexpr const char* IOX2_TYPE_NAME = "GenericHeader";
uint32_t frame_id;
uint64_t timestamp; //
};
struct ImageData720p {
static constexpr const char* IOX2_TYPE_NAME = "ImageData720p";
uint16_t WIDTH = 1280;
uint8_t image_data<uint8_t, 1280 * 720 * 4>;
};
This shouldn't be a problem here, no matter how large std::unique_ptr<ImageData720p> data = std::make_unique<ImageData720p>(); But if you do not need it locally, you can use C++ placement new to handle exactly this use case with: auto uninit_sample = publisher.loan_uninit().expect("");
// use placement new here
new (&sample.payload_mut()) ImageData720p();
// populate the image index by index
sample.payload_mut().image_data[0] = 123;
// populate the image via memcpy
memcpy(sample.payload_mut().image_data, image_source_ptr, 1280 * 720 * 4);
// mark sample as initialized
auto sample = assume_init(std::move(sample));
send(std::move(sample)); |
Beta Was this translation helpful? Give feedback.
-
@elfenpiff Finally it works! Thanks a lot!. OMG, it's so simple. Indeed, I've tried that without in-place, and it didn't work. I thought any vector stuff is the problem. :) To clarify, the exact type in C++ std::array<uint8_t, 1280 * 720 * 4> image_data; For the Python correspondence. ("image_data", ctypes.c_uint8 * 1280 * 720 * 4), All 4 cases work:cpp->cpp |
Beta Was this translation helpful? Give feedback.
@ElliotHYLee We are currently working on memory layout compatible data types and the first implementation will come with a Rust <-> C++ string and vector. The python part will come later as soon as we have secured some funding for it.
So for now, you can use this:
Python