-
Notifications
You must be signed in to change notification settings - Fork 58
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
Implemented RCL global argument parsing. #122
Changes from 3 commits
30b2f06
d3122ca
232a4e0
7d3c0a3
c51b096
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -96,6 +96,14 @@ internal delegate RCLRet NativeRCLActionDestroyServerHandleType( | |
|
||
internal static NativeRCLActionDestroyServerHandleType native_rcl_action_destroy_server_handle = null; | ||
|
||
[UnmanagedFunctionPointer(CallingConvention.Cdecl)] | ||
internal delegate string NativeRCLGetStringType( | ||
SafeNodeHandle nodeHandle); | ||
|
||
internal static NativeRCLGetStringType native_rcl_get_name_handle = null; | ||
|
||
internal static NativeRCLGetStringType native_rcl_get_namespace_handle = null; | ||
|
||
static NodeDelegates() | ||
{ | ||
_dllLoadUtils = DllLoadUtilsFactory.GetDllLoadUtils(); | ||
|
@@ -182,6 +190,18 @@ static NodeDelegates() | |
NodeDelegates.native_rcl_action_destroy_server_handle = | ||
(NativeRCLActionDestroyServerHandleType)Marshal.GetDelegateForFunctionPointer( | ||
native_rcl_action_destroy_server_handle_ptr, typeof(NativeRCLActionDestroyServerHandleType)); | ||
|
||
IntPtr native_rcl_get_name_handle_ptr = _dllLoadUtils.GetProcAddress( | ||
nativeLibrary, "native_rcl_get_name_handle"); | ||
NodeDelegates.native_rcl_get_name_handle = | ||
(NativeRCLGetStringType)Marshal.GetDelegateForFunctionPointer( | ||
native_rcl_get_name_handle_ptr, typeof(NativeRCLGetStringType)); | ||
|
||
IntPtr native_rcl_get_namespace_handle_ptr = _dllLoadUtils.GetProcAddress( | ||
nativeLibrary, "native_rcl_get_namespace_handle"); | ||
NodeDelegates.native_rcl_get_namespace_handle = | ||
(NativeRCLGetStringType)Marshal.GetDelegateForFunctionPointer( | ||
native_rcl_get_namespace_handle_ptr, typeof(NativeRCLGetStringType)); | ||
} | ||
} | ||
|
||
|
@@ -440,5 +460,9 @@ private static CancelResponse DefaultCancelCallback(ActionServerGoalHandle goalH | |
{ | ||
return CancelResponse.Reject; | ||
} | ||
|
||
public string GetName() => NodeDelegates.native_rcl_get_name_handle(Handle); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think we should use a get-only-computed property here instead of getter methods, but I can see arguments for using a method here as well. Have you considered properties instead? public string Name => NodeDelegates.native_rcl_get_name_handle(Handle);
public string Namespace => NodeDelegates.native_rcl_get_namespace_handle(Handle); There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I agree. I think I will also include a FullyQualifiedNodeName in the same way as it is useful for the parameter handling code. |
||
|
||
public string GetNamespace() => NodeDelegates.native_rcl_get_namespace_handle(Handle); | ||
} | ||
} |
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.
Returning a
string
directly from an PInvoke is a new pattern that isn't used anywhere yet in this code base.After some research this seems problematic:
from https://www.mono-project.com/docs/advanced/pinvoke/
My understanding of this is the following:
While this might work for linux as the runtime and the
get_str_cpy
use the same allocator, this will most certainly break on windows as thenCoTaskMemFree()
will get called on the pointer allocated bymalloc()
.So I would propose to use the method mentioned from the mono documentation and return an
IntPtr
instead and useMarshal.PtrToStringAnsi()
This method is used in the marshalling of the ROS messages as well.
Normally it should be fine to access the returned pointer directly after the call and pass it to
Marshal.PtrToStringAnsi()
as the livetime of the returnedchar*
is documented to be valid as longe as thercl_node_t
is valid:But I think we should add additional
SafeHandle.DangerousAddRef()
/SafeHandle.DangerousRelease()
around this to stay safe when some other thread doesDispose()
theSafeNodeHandle
(disposing nodes isn't implemented right now, but if we don't add this right now we will forget and only add it after a long memory management debugging session ;))But it's getting late here, so maybe I need to think about this again after some sleep :)
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.
Very insightful analysis. I had noticed the behaviour of freeing the memory from the managed side and assumed that simply returning a copy of the string was the best way to handle that at the time. I'll have to put some time into considering how this affects other code I have written after this initial pull request!