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
Missing try/catch in some C API wrappers #95
Comments
Thats a good point. The The try/catch macros arent exactly indiscriminate, its just that they are only found for setters, not getter calls. Most getter calls don't throw under regular operation. But its pretty easy to have an underlying layer throw when something disconnects, or perhaps a wrong name or key is used. Without obliterating the API, some getters can be changed to return null on error. But many just return a bool, double, range... theres no good way to change that. It would be possible to put try/catches on all calls that simply log + set the error message when thrown, but dont actually indicate any error to the user through the arguments. In this case, the user could check the error message or null, or we could provide something like errno. |
Yeah, sorry, by applying them indiscriminately, I meant that they should be everywhere, including getters and some other methods that don't have them yet (direct buffer access API, stream API, etc.), so there's no opportunity for an exception getting across the boundary. But as you pointed out, this does present an issue for the getters. An errno-style solution would be ABI backwards compatible, but it still technically changes the usage for C programs moving forward to fully adopt it, so one could argue it's a different API. Personally, I would prefer if the direct getters got deprecated for a consistent return code API (like the setters use), rather than an errno-style one. It might be a little more verbose (and in some cases awkward with |
c_error_work Created a work branch to address some of this. This branch has an extra macro to deal with the catch with arbitrary return. The idea is to get this out as a fix that’s non breaking for 0.5 series (then break the API for 0.6!). There is no reason not to get try/catches on all of the calls that throw.
noexcept In terms of the C wrapper, this basically means that the noexcept calls dont need try/catches. But the others definitely should get try/catch. API changes
I guess the point is that the changes would be API backwards compatible as well, so its safe to do without breaking :-P Code that wasn't checking for errors, can continue to not check for errors.
Your right, that would be totally consistent. I also have this worry of making the code unwieldy at the same time.
|
Noice! Thanks for the quick turnaround. In the meanwhile, I've got the SoapySDRSource and SoapySDRSink via the C API working well in LuaRadio now, which should bring a lot more SDR support to the LuaRadio project. I still think return codes (and NULL on pointers) on getters is better than sharing the error path with the values and checking for NaNs and -1 and members of structs and whatnot, but you've heard my vote already :-). Perhaps in a future version. Thanks for being receptive nonetheless. |
Awesome news! For an update: The maint branch (pre 0.5.3 release) will have try/catches for all of the device calls, even the ones that should not throw. Some of the calls cant return a status, so there is an added For the master branch, we have some minor API changes so far. Many of the remaining void return calls now return a integer status when possible. Some breaking API changes are planned for the next major release: removed deprecations, renames for some of the more obscure C calls, and general additions here and there.
Asking the user to actually check for NANs and other stuff like that is messy and basically doesnt work. I consider this the value that is set on return during a failure. But I'm hoping that in this case, the user can call lastStatus() in these cases if they care to follow through with the error checking safety. I appreciate the feedback. I think I do need to break the API a little more :-) Just want to consider the trade-offs. Function overloads and memory management make it easier to not break things in C++, but I think some C apps might have to ifdef some code during the transition. |
Thanks Josh! 👍 |
The C API wrappers
SoapySDRDevice_make()
andSoapySDRDevice_makeStrArgs()
are missing try/catch wrappers and can leak C++ exceptions to the calling C program, in cases when no compatible module is found or when a module constructor raises an exception. This results in abrupt termination of the calling C program.This can be observed with the stock C API example:
It looks like
DeviceC.cpp
addresses many of these cases with the__SOAPY_SDR_C_TRY
and__SOAPY_SDR_C_CATCH
macros, but these macros probably need to be applied more indiscriminately, as some seemingly benign module methods (like the RTL-SDR module'sgetGain()
) can still raise an exception that would leak through.If I get a chance this week, I'll try to make and PR the changes.
The text was updated successfully, but these errors were encountered: