I have a few but similar set/get functions imported from a DLL that interface with a communication bus. These all should ideally share an identical wrapper doing some error checks, mutex handling etc. The code snippet below is a basic representation of it. It compiles and all functions seem to work except that WrappedGet() does not modify the referenced variable data. Ideas?
static UInt32 common_var = 0;
// Reduce boilerplate by wrapping all calls to the DLL with this
static private bool CommonWrapper<T1>(Action<T1> dll_function_handle, ref T1 data)
{
// Commmon code for mutex handling etc
/// ....
// Call to function handle, sometimes data is in-parameter, other times out-param
dll_function_handle(data);
return true;
}
static private void DllSet(UInt32 data) { common_var = data; }
static public void WrappedSet(UInt32 data) { CommonWrapper<UInt32>((UInt32 a) => DllSet(a), ref data); }
static private void DllGet(ref UInt16 data){ data = 1234; }
// WrappedGet does not modify argument "data" because of the lambda? What to do?
static public void WrappedGet(ref UInt16 data) { CommonWrapper<UInt16>((UInt16 a) => DllGet(ref a), ref data); }
EDIT:
This works:
static public void WrappedGet(ref UInt16 data)
{
UInt16 local = 0;
CommonWrapper<UInt16>((UInt16) => DllGet(ref local), ref data);
data = local;
}
It is a bit awkward though, is it the right way to do this?
The problem in you code is that the Action does not take the parameter as a ref
so a copy of data
will be created before it is given to the DllGet
method.
// vvvvvvvvvvvvvvvvvvvvvvvvvvv
CommonWrapper<UInt16>((UInt16 a) => DllGet(ref a), ref data);
Instead of an Action
you could define a delegate and use a ref
in the lambda.
So you need to add an delegate
private delegate void WrappedFunction<T>(ref T data);
And need to use it in the CommonWrapper
// vvvvvvvvvvvvvvvvvvv
static private bool CommonWrapper<T1>(WrappedFunction<T1> dll_function_handle, ref T1 data)
{
// Your code here
}
And you need to add the ref
to the lambda
// vvv
static public void WrappedGet(ref UInt16 data) { CommonWrapper<UInt16>((ref UInt16 a) => DllGet(ref a), ref data); }
So the whole code looks like this:
private delegate void WrappedFunction<T>(ref T data);
// Reduce boilerplate by wrapping all calls to the DLL with this
static private bool CommonWrapper<T1>(WrappedFunction<T1> dll_function_handle, ref T1 data)
{
// Commmon code for mutex handling etc
// ....
// Call to function handle, sometimes data is in-parameter, other times out-param
dll_function_handle(ref data);
return true;
}
static private void DllSet(UInt32 data) { common_var = data; }
static public void WrappedSet(UInt32 data) { CommonWrapper<UInt32>((ref UInt32 a) => DllSet(a), ref data); }
static private void DllGet(ref UInt16 data){ data = 1234; }
static public void WrappedGet(ref UInt16 data) { CommonWrapper<UInt16>((ref UInt16 a) => DllGet(ref a), ref data); }