2015-11-25 5 views
0

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

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

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

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

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 ''. Означает ли это, что это пусто? если да, то почему он по-прежнему отправляет случайные числа в мой ПЛК?

ответ

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, у вас есть проблема с повреждением памяти. В любом случае, этот код неверен.
+0

Е. Я заметил, что мне пришлось изменить свой буфер на массив, я сделал это, и он теперь решен. Спасибо за информацию! :) – Bart