void IDataDistributionChannelCallbackLow.OnUnderlyingEvent(IntPtr opaque, IntPtr channelHandle, UnderlyingEvent uEvent)
        {
            if (uEvent.IsDataAvailable)
            {
                Timestamp = uEvent.Timestamp;
                Offset    = uEvent.Offset;

                byte[] data = null;
                if (uEvent.Buffer != IntPtr.Zero)
                {
                    data = new byte[uEvent.BufferLength.ToInt64()];
                    Marshal.Copy(uEvent.Buffer, data, 0, data.Length);
                }

                string key     = null;
                byte[] keyData = null;
                if (uEvent.Key != IntPtr.Zero)
                {
                    keyData = new byte[uEvent.KeyLen.ToInt64()];
                    Marshal.Copy(uEvent.Key, keyData, 0, keyData.Length);
                    try
                    {
                        key = Encoding.ASCII.GetString(keyData);
                    }
                    catch (Exception ex)
                    {
                        OnConditionOrError(OPERATION_RESULT.DDM_INVALID_DATA, 0, ex.Message);
                        key = null;
                    }
                }

                OnDataAvailable(key, data);
                DataAvailable?.Invoke(this, new DataAvailableEventArgs(this, key, data));
            }
            else
            {
                OnConditionOrError(uEvent.Condition, uEvent.NativeCode, uEvent.SubSystemReason);
                ConditionOrError?.Invoke(this, new ConditionOrErrorEventArgs(this, uEvent.Condition, uEvent.NativeCode, uEvent.SubSystemReason));
            }
        }
        void IDataDistributionChannelCallbackLow.OnUnderlyingEvent(IntPtr opaque, IntPtr channelHandle, UnderlyingEvent uEvent)
        {
            if (uEvent.IsDataAvailable)
            {
                byte[] data = new byte[uEvent.BufferLength.ToInt64()];
                Marshal.Copy(uEvent.Buffer, data, 0, data.Length);

                byte[] keyData = new byte[uEvent.KeyLen.ToInt64()];
                Marshal.Copy(uEvent.Key, keyData, 0, keyData.Length);
                string key = string.Empty;
                try
                {
                    key = System.Text.Encoding.ASCII.GetString(keyData);
                }
                catch (Exception ex) { key = ex.Message; }
                OnDataAvailable(uEvent.ChannelName, key, data);
                DataAvailable?.Invoke(this, new DataAvailableEventArgs(uEvent.ChannelName, key, data));
            }
            else
            {
                OnConditionOrError(uEvent.ChannelName, uEvent.Condition, uEvent.NativeCode, uEvent.SubSystemReason);
                ConditionOrError?.Invoke(this, new ConditionOrErrorEventArgs(uEvent.ChannelName, uEvent.Condition, uEvent.NativeCode, uEvent.SubSystemReason));
            }
        }