Взаимодействие C # с очень старым элементом управления ActiveX - PullRequest
0 голосов
/ 17 декабря 2018

Я пытаюсь интегрировать старое радио RFSpace SDR-IQ в существующую программу на C #.Информация SDR-IQ: http://www.rfspace.com/RFSPACE/SDR-IQ.html

SDR-IQ подключается к ПК через USB.

Я обнаружил очень старый элемент управления ActiveX, который успешно отображается в диалоговом окне C # (после регистрацииDLL вручную).Элемент управления ActiveX: http://www.moetronix.com/files/sdr14xsdk127.zip

Вот метаданные C # для элемента управления:

namespace AxSDR14XLib
{
    [DefaultEvent("StatusChange")]
    [DesignTimeVisible(true)]
    public class AxSDR14X : AxHost
    {
        public AxSDR14X();

        [DispId(12)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public virtual short BootRevision { get; set; }
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        [DispId(1)]
        public virtual int ClockFrequency { get; set; }
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        [DispId(2)]
        public virtual string DeviceName { get; set; }
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        [DispId(3)]
        public virtual int FirmwareRevision { get; set; }
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        [DispId(4)]
        public virtual int HFgain { get; set; }
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        [DispId(5)]
        public virtual int IFfilter { get; set; }
        [DispId(10)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public virtual int IFgain { get; set; }
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        [DispId(6)]
        public virtual int InputSource { get; set; }
        [DispId(7)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public virtual int InterfaceVersion { get; set; }
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        [DispId(13)]
        public virtual double IQOffset { get; set; }
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        [DispId(8)]
        public virtual int NCOfrequency { get; set; }
        [DispId(11)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public virtual int SampleRate { get; set; }
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        [DispId(9)]
        public virtual string SerialNumber { get; set; }

        public event _DSDR14XEvents_DataRdyEventHandler DataRdy;
        public event _DSDR14XEvents_StatusChangeEventHandler StatusChange;
        public event EventHandler UartDataRdy;

        public virtual void AboutBox();
        protected override void AttachInterfaces();
        public virtual void CloseI2CPort();
        public virtual void CloseSpiPort();
        public virtual void CloseUartPort();
        protected override void CreateSink();
        protected override void DetachSink();
        public virtual int GetDoubleData(ref double dataArray);
        public virtual bool GetFftDoubleData(ref double dataArray);
        public virtual bool GetFftScreendata(int plotHeght, int plotWidth, double maxdB, double mindB, int startFreq, int endFreq, ref int plotBuf);
        public virtual int GetIntegerData(ref short dataArray);
        public virtual int GetLongData(ref int dataArray);
        public virtual short GetUartData(ref short uartRxArray);
        public virtual void InitControl();
        public virtual void OpenI2CPort(short adrWidth);
        public virtual void OpenSpiPort(short clkPolarity);
        public virtual void OpenUartPort(int baudRate, short parity, bool flowControl);
        public virtual void ResetFftAverage();
        public virtual void Send6620RawCmd(short address, short d0, short d1, short d2, short d3, short d4);
        public virtual void SendI2CData(ref short txDataArray, short numDataItems);
        public virtual void SendSpiData(int data32High, int data32Low, short numberBits);
        public virtual void SendUartData(ref short uartTxArray, short numDataItems);
        public virtual void SetupFFT(int fftPoints, short fftaverages, bool fftInverted);
        public virtual void Start(short blocks, short mode);
        public virtual void Stop();
    }

Методы .InitControl() и .Start() элемента управления работают правильно.События StatusChange и DataRdy также работают.Итак, элемент управления успешно связывается с радио.

Проблема возникает, когда я пытаюсь получить данные из элемента управления в обработчике событий DataRdy через .GetLongData().

Несмотря на многие часы поиска в Google, независимо от того, что я пытаюсь, мой код просто вылетает с ошибкой:

Программа '[9036] sdriq.vshost.exe: Managed (v4.0.30319) 'завершен с кодом -1073741819 (0xc0000005).

Нет более подробной информации о сбое в объекте Exception.

Вот один примервызов .GetLongData(), который не удался:

private int[] m_SdrData = new int[40000];

private void axSDR14X1_DataRdy(object sender, AxSDR14XLib._DSDR14XEvents_DataRdyEvent e)
{
    unsafe
    {
        var unmanagedArray = (int*)Marshal.AllocHGlobal(m_SdrData.Length * sizeof(int));
        int samples = axSDR14X1.GetLongData(ref unmanagedArray[0]);
        for (int i = 0; i < m_SdrData.Length; i++) m_SdrData[i] = unmanagedArray[i];
        Marshal.FreeHGlobal((IntPtr)unmanagedArray);
    }
}

Первоначальный автор элемента управления ответил, когда я написал по адресу в файле readme элемента управления: «Да, dll, которую я написал давно, был dll activex иЯ не думаю, что uSoft разрешает передавать указатели памяти больше. Я не знаю C #, но я подозреваю, что он также не разрешает прямые указатели памяти. "

Так что, хотя это явно не указано, я на 99%уверен, что элемент управления написан на C ++.

Я не очень разбираюсь в вызовах C ++ из C #.Учитывая подпись .GetLongData, показанную выше, я ищу помощь в поиске волшебной комбинации unsafe, IntPtr, Marshal.AllocHGlobal и т. Д., Чтобы получить данные радио от неуправляемого элемента управления ActiveX C ++ в мойуправляемый код C #.

Большое спасибо заранее за любую помощь.

...