-
Notifications
You must be signed in to change notification settings - Fork 55
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
POC: Rust Wrapper for 1DS C++ SDK #1225
base: main
Are you sure you want to change the base?
Conversation
@microsoft-github-policy-service agree company="Microsoft" |
} | ||
|
||
fn log(&self, record: &Record) { | ||
if unsafe { CONSOLE_ENABLED } && self.enabled(record.metadata()) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These fields should probably be changed to use std::sync::atomc::AtomicBool
, which will allow this code to be safe.
Using static mut
is unsafe because it allows for race conditions, which are undefined behavior.
pub fn to_leaky_c_str(value: &str) -> *const i8 { | ||
let c_str = Box::new(CString::new(value.clone()).unwrap()); | ||
let ptr = c_str.as_ptr() as *const i8; | ||
mem::forget(c_str); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can this be Box::into_raw(c_str) as *const i8
instead?
} | ||
|
||
/// The global `Tracer` provider singleton. | ||
static GLOBAL_LOG_MANAGER: Lazy<RwLock<LogManager>> = Lazy::new(|| RwLock::new(LogManager::new())); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a reason this uses Lazy
instead of just typing this field as RwLock<LogManager>
?
* This will leak memory | ||
*/ | ||
pub fn to_leaky_c_str(value: &str) -> *const i8 { | ||
let c_str = Box::new(CString::new(value.clone()).unwrap()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I suspect the value.clone()
call doesn't do anything. It could probably be simplified to just value
.
} | ||
|
||
fn to_str(&self) -> Result<&str, std::str::Utf8Error> { | ||
unsafe { CStr::from_ptr(self.as_ptr()).to_str() } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a reason this is not just core::str::from_utf8(&self.bytes)
? What merits using unsafe code here?
result | ||
} | ||
|
||
pub fn evt_upload(handle: &evt_handle_t) -> evt_status_t { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Because you are directly exposing evt_handle_t
outside your crate, and this type has unsafe pointers in it, these functions are actually unsafe to call. They allow a safe caller to violate type safety.
You can fix this in one of several ways:
- Don't expose these functions outside this crate.
- Don't expose
evt_context_t
, and instead define anEvtContext
wrapper type which containsevt_context_t
but does not expose it outside of the crate. - Mark these functions
unsafe
.
[dependencies] | ||
chrono = { version = "0.4.30" } | ||
log = { version = "0.4.20" } | ||
once_cell = "1.12.0" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a reason to use once_cell
, now that Once
and OnceLock
are part of the Rust standard library?
pub mod appender; | ||
pub mod types; | ||
|
||
#[derive(Clone)] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is log_handle
a pointer or a handle that was received from the underlying C API? If so, then I don't think this Clone call is correct or safe.
Int(i64), | ||
} | ||
|
||
pub type TelemetryPropertyBag = HashMap<&'static str, TelemetryProperty>; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's a matter of taste, but I generally prefer to simply see HashMap<&str, TelemetryProperty>
instead of a type alias.
TelemetryItem { | ||
name: StringProperty::new(name), | ||
data: TelemetryPropertyBag::new(), | ||
time: Option::None, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use None
instead of Option::None
.
@CDFriend This looks to be a good addition. when you have time, can you please make it ready for review :) |
* Making quality of life improvements to the types * Adding testing to types
a95e623
to
5c3a0ef
Compare
@msft-tsharp Sorry for late reply. Do you think you can still work on resolving it ? |
What is this?
Adds a Rust "wrapper" to the 1DS C++ SDK, which will allow the SDK to be imported into Rust projects as a crate. The crate interacts with the C API of the SDK (instead of C++) as this will ensure a stable binary interface between the Rust layer and C++ layer of the project.
Project Structure
Crates:
Limitations
i64
andstring
telemetry fields are supported.Build Instructions
Win32-Lib
configuration for the x64 arch.