Closed puli1027 closed 1 year ago
Hi, can you be a bit more specific - what did you try, and how is your data laid out?
I try defined a Struct ,but there is a error.
use zerocopy::{AsBytes, FromBytes};
#[derive(Default,AsBytes,FromBytes)]
#[repr(C)]
pub struct TestStruct {
pub var1: i16,
pub var2: i32,
pub var3: f32,
pub var4: f64,
}
error[E0277]: the trait bound `TestStruct: HasPadding<false>` is not satisfied
--> src\models\my_model.rs:5:12
|
5 | pub struct TestStruct {
| ^^^^^^^^^^ the trait `HasPadding<false>` is not implemented for `TestStruct`
|
= help: the trait `HasPadding<true>` is implemented for `TestStruct`
note: required by a bound in `assert_no_padding`
--> src\models\my_model.rs:3:18
|
3 | #[derive(Default,AsBytes,FromBytes)]
| ^^^^^^^ required by this bound in `assert_no_padding`
= note: this error originates in the derive macro `AsBytes` (in Nightly builds, run with -Z macro-backtrace for more info)
OK, that's because even if repr(C)
padding is added if field layout requires it. Here, 16 bits of padding is inserted between var1
and var2
because the i32
needs to lie at a 32-bit boundary.
Can you try #[repr(C, packed)]
instead, that should remove the padding?
The error on the structure disappeared
use zerocopy::{AsBytes, FromBytes};
#[derive(Default,AsBytes,FromBytes)]
#[repr(C,packed)]
pub struct TestStruct {
pub var1: i16,
pub var2: i32,
pub var3: f32,
pub var4: f64,
}
but,there are still errors in the code.
fn main() -> anyhow::Result<()> {
// Open a connection to an ADS device identified by hostname/IP and port.
// For TwinCAT devices, a route must be set to allow the client to connect.
// The source AMS address is automatically generated from the local IP,
// but can be explicitly specified as the third argument.
let client = ads::Client::new(("plchost", ads::PORT), ads::Timeouts::none(),
ads::Source::Auto)?;
// Specify the target ADS device to talk to, by NetID and AMS port.
// Port 851 usually refers to the first PLC instance.
let device = client.device(ads::AmsAddr::new([5, 32, 116, 5, 1, 1].into(), 851));
// Ensure that the PLC instance is running.
assert!(device.get_state()?.0 == ads::AdsState::Run);
// Request a handle to a named symbol in the PLC instance.
let handle = Handle::new(device, "MY_SYMBOL")?;
// Read data in form of an u32 from the handle.
let value = handle.read_value::<TestStruct>()?;
println!("MY_SYMBOL value is {}", value);
// Connection will be closed when the client is dropped.
Ok(())
}
Below is the error message
error[E0277]: the trait bound `TestStruct: zerocopy::AsBytes` is not satisfied
--> src\ads_ffi\data_ffi.rs:72:37
|
72 | let value = handle.read_value::<TestStruct>()?;
| ^^^^^^^^^^ the trait `zerocopy::AsBytes` is not implemented for `TestStruct`
|
= help: the following other types implement trait `zerocopy::AsBytes`:
()
AmsNetId
PhantomData<T>
String80
WString80
[T; 0]
[T; 1024]
[T; 10]
and 100 others
note: required by a bound in `Handle::<'c>::read_value`
--> D:\AppInstall\rust\.cargo\registry\src\mirrors.tuna.tsinghua.edu.cn-2eab394af869c8a2\ads-0.4.3\src\symbol.rs:54:36
|
54 | pub fn read_value<T: Default + AsBytes + FromBytes>(&self) -> Result<T> {
| ^^^^^^^ required by this bound in `Handle::<'c>::read_value`
Please give me some guidance,thanks
I don't get this error. Please make sure that the version of zerocopy
you depend on is the same as the one ads
depends on (0.3.0). Otherwise there will be two incompatible versions in the dependency tree.
Indeed, when I changed the version of zerocopy to 0.3.0, the error disappeared. thanks so much!
I wanted to read and write structs, but I didn't succeed。