Запись Snap7 в ПЛК S7-1200

Я пытаюсь написать что-то в моем ПЛК Siemens с помощью приложения C ++ / CLI.

Чтение в порядке (кроме первого чтения, дает нечетные значения).

Но писательство делает нечто совершенно иное, чем то, что я хочу.

ниже вы можете найти код:

    private: void WriteSiemensDB()
    {
        byte* buffer;

        if (ConnectToSiemensPLC()) //Check if you are connected to PLC
        {
        String^ msg;
        int DBNumber = 2;
        bool NDR;
                                                       
        //Getting the values 1 time so buffer has a value
        buffer = sPLC->ReadDB(DBNumber);
        
        //give variables a value to write it to the PLC
        NDR = true;
        
        sPLC->SetBitAt(buffer, 0, 0, NDR); //Convert a bool to a bit
    
        msg = sPLC->WriteDB(DBNumber, buffer); //write to the Datablock in Siemens

        MessageBox::Show(msg); //Show if it worked or not
    }
}

Метод sPLC- ›SetBitAt:

void SiemensPLC::SetBitAt(byte buffer[], int Pos, int Bit, bool Value)
{
    byte Mask[] = { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 };
    if (Bit < 0) Bit = 0;
    if (Bit > 7) Bit = 7;

    if (Value)
    {
        buffer[Pos] = (byte)(buffer[Pos] | Mask[Bit]);
    }
    else
    {
        buffer[Pos] = (byte)(buffer[Pos] & ~Mask[Bit]);
    }
}

WriteDB метод:

System::String^ SiemensPLC::WriteDB(int DBnumber, byte buffer[])
{
    int Result;
    String^ msg;
    Result = MyClient->DBWrite(DBnumber, 0, 80, buffer);

    if (Result == 0)
    {
        msg = "Gelukt!"; //success
    }
    else
    {
        msg = "Mislukt, error:" + Result; //failed
    }
    return msg;
}

Я действительно получаю сообщение Gelukt, но оно все равно записывает значения rwong. Значит что-то идет не так с заполнением моего buffer. Я что-то не так делаю с буфером?

В C # у меня такое же приложение, за исключением того, что буфер byte buffer[];

Мои вопросы:

  • В чем разница между byte* buffer; в C ++ и byte buffer[]; в C #?
  • Когда я наводю указатель мыши на свой буфер во время отладки, отображается buffer* = 0 ''. Значит ли это, что он пуст? Если да, то почему он все еще отправляет случайные числа на мой ПЛК?

person Bart    schedule 25.11.2015    source источник


Ответы (1)


В чем разница между byte* buffer; в C ++ и byte buffer[]; в C #?

Предполагая, что у вас есть typedef unsigned char byte;:

В C ++ / CLI byte* buffer; объявляет переменную buffer, которая является указателем на byte. В C # вы пишете это как byte* buffer; в контексте unsafe. Синтаксис такой же.

В C # byte[] buffer; объявляет переменную buffer, которая представляет собой управляемый массив byte значений. Синтаксис C ++ / CLI для этого - array<byte> buffer;.

Обратите внимание, что byte buffer[N]; - это синтаксис C ++ для собственного массива, что не одно и то же. Тот может распасться на указатель byte*.

Похоже, ваш код использует собственный буфер памяти, но без источника ReadDB невозможно сказать это наверняка.

Когда я наводю указатель мыши на свой буфер во время отладки, отображается buffer* = 0 ''. Значит ли это, что он пуст? Если да, то почему он все еще отправляет случайные числа на мой ПЛК?

Это означает, что первый байт в вашем буфере - 0. Если ваш буфер должен содержать строковые данные C, это означает, что он содержит пустую строку.

Я что-то не так делаю с буфером?

Скорее всего. Но я не могу точно сказать, что случилось, потому что вы не разместили источник ReadDB.

Однако есть пара красных флажков:

  • Какой размер буфера? Ваш код не знает, что возвращает ReadDB, поэтому как вы должны гарантировать, что не переполняете его?
  • Кто является владельцем буфера, то есть: кто должен его освобождать? Он предположительно живет в куче, поэтому в вашем коде происходит утечка памяти. Если он находится в стеке ReadDB, у вас проблема с повреждением памяти. В любом случае, этот код неверен.
person Lucas Trzesniewski    schedule 25.11.2015
comment
Я заметил, что мне пришлось преобразовать буфер в массив, я сделал это, и теперь проблема решена. Спасибо за информацию! :) - person Bart; 03.12.2015