Closed Indra5196 closed 3 years ago
@Indra5196 to implement a zero copy data transfer we us a shared memory approach. This requires that every data structure needs to be stored in there and that they do not use the heap.
An std::vector
uses the heap to acquire memory to store the elements in there. This leads to the following problem.
std::vector
which then would like to access his heap memory to read the elements which are stored in the process space of your sender application and this causes a segmentation fault since you as a stranger process are not allowed to access memory of another process. This is only with shared memory allowed.Solution:
Update your structure so that it uses our cxx::vector
implementation and you are good to go.
struct MyStruct {
cxx::vector<char, 1337> charArray;
};
It can be used like a normal vector but it does not use the heap under the hood. This is why you have to provide the maximum cxx::vector
capacity at compile time - in this case it is 1337
.
I mainly want to know whether we can actually transfer complex data types with Iceoryx or we need to follow some workaround?
You can transfer every data type which does not use the heap. Those are for instance c style arrays, all the POD types (int, float, char ...), std::array
and some more. If you encounter this issue again you could take a look at: https://github.com/eclipse-iceoryx/iceoryx/tree/master/iceoryx_utils/include/iceoryx_utils/cxx where you find data types which are not using the heap and can be used as an alternative for std::vector
for instance. There usage should be similar to the stl containers.
For std::map
or and std::set
we do not have an alternative at the moment but if the need arises on your end please create an issue.
Thank you very much. That helped a lot!
Added an item in #482 that we need to document the limitations of what can be transmitted via shared memory. Closing this issue and we can continue the wishlist of data types and possible solutions in #594
Required information
Operating system: Ubuntu 18.04 LTS
Compiler version: GCC 7.5.0
Iceoryx versioin: 0.90.0.0
Observed result or behaviour: I created a structure which is as follows: struct MyStruct { std::vector charArray;
};
I am using this in place of "RadarObject" struct in the untyped example
Publisher code: auto result = untypedPublisher.loan(sizeof(MyStruct)); if (!result.has_error()) { auto& sample = result.value(); // In the untyped API, the returned sample is a void pointer, therefore the data must be constructed // in place auto object = static_cast<MyStruct>(sample.get()); object = MyStruct(); object->charArray.push_back('A'); sample.publish(); }
Subscriber code: if (untypedSubscriber.getSubscriptionState() == iox::SubscribeState::SUBSCRIBED) { untypedSubscriber.take() .and_then([](iox::popo::Sample& sample) {
auto object = static_cast<const MyStruct*>(sample.get());
std::cout << "Got value: " << object->charArray.at(0) << std::endl;
})
.if_empty([] { std::cout << std::endl; })
.or_else( { std::cout << "Error receiving chunk." << std::endl; });
}
else
{
std::cout << "Not subscribed!" << std::endl;
}
When I run my application, publisher crashes.
I have tried something similar with Iceoryx version 0.17.0.2, but I was receiving blanks at the receiver
I mainly want to know whether we can actually transfer complex data types with Iceoryx or we need to follow some workaround?
Expected result or behaviour: Data transfers successfully