diff --git a/ni-fpga/src/errors.rs b/ni-fpga/src/errors.rs index 69e2e3a..5db9449 100644 --- a/ni-fpga/src/errors.rs +++ b/ni-fpga/src/errors.rs @@ -18,4 +18,6 @@ pub enum Error { FixedPointPrecision(f64, u8, u8, bool), #[error("Library Open Failed: {0}")] DlOpen(DlOpenError), + #[error("Cannot close an unowned fpga session")] + ClosingUnownedSession, } diff --git a/ni-fpga/src/nifpga.rs b/ni-fpga/src/nifpga.rs index 86abbc0..96028e5 100644 --- a/ni-fpga/src/nifpga.rs +++ b/ni-fpga/src/nifpga.rs @@ -23,6 +23,7 @@ impl StatusHelper for ffi::Status { pub struct NiFpga { session: Session, api: NiFpgaApiContainer, + owns_session: bool, } macro_rules! type_wrapper { @@ -53,11 +54,7 @@ macro_rules! type_wrapper { .to_result() } - pub fn $writearr_fun_name( - &self, - indicator: Offset, - value: &[$type], - ) -> Result<(), Error> { + pub fn $writearr_fun_name(&self, indicator: Offset, value: &[$type]) -> Result<(), Error> { self.api .base .$writearr_ffi_name(self.session, indicator, value.as_ptr(), value.len()) @@ -195,6 +192,19 @@ impl NiFpga { } } + pub fn from_session(session: Session) -> Result { + let api = match NiFpgaApi::load() { + Ok(api) => api, + Err(err) => return Err(Error::DlOpen(err)), + }; + + Ok(Self { + session, + api, + owns_session: false, + }) + } + pub fn open( bitfile: &CString, signature: &CString, @@ -218,16 +228,24 @@ impl NiFpga { ) .to_result() { - Ok(_) => Ok(Self { session, api }), + Ok(_) => Ok(Self { + session, + api, + owns_session: true, + }), Err(err) => Err(err), } } pub fn close(self, attribute: u32) -> Result<(), Error> { - self.api - .base - .NiFpgaDll_Close(self.session, attribute) - .to_result() + match self.owns_session { + true => self + .api + .base + .NiFpgaDll_Close(self.session, attribute) + .to_result(), + false => Err(Error::ClosingUnownedSession), + } } } @@ -235,6 +253,8 @@ impl Drop for NiFpga { fn drop(&mut self) { // TODO figure out what to do here with attribute // and the return value - self.api.base.NiFpgaDll_Close(self.session, 0); + if self.owns_session { + self.api.base.NiFpgaDll_Close(self.session, 0); + } } }