Snap7写入S7-1200 PLC。

时间:2021-02-11 16:43:33

I'm trying to write something to my Siemens PLC with a C++/CLI application.

我正试着用c++ /CLI应用程序写一些东西给我的西门子PLC。

Reading is ok (except the first time it reads it gives odd values).

阅读是可以的(除了第一次读它会给出奇怪的值)。

But writing is doing something completely different then what I want.

但是写作是在做一件完全不同的事情,那就是我想要的。

below you can find the code:

下面你可以找到代码:

    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
    }
}

The sPLC->SetBitAt method:

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 method:

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;
}

I actually get the message "Gelukt", but it still writes the rwong values. So something goes wrong with filling my buffer. Am I doing something wrong in with the buffer?

我实际上得到了“Gelukt”的消息,但它仍然写rwong值。我的缓冲区填满了问题。我是不是做错了什么?

In C# I have the same kind of application except the buffer is a byte buffer[];

在c#中,我有相同的应用程序,除了缓冲区是一个字节缓冲区[];

My questions are:

我的问题是:

  • Whats the difference between a byte* buffer;in C++ and a byte buffer[]; in C#?
  • 在C++和字节缓冲之间的区别是什么?在c#中?
  • When I mouse over on my buffer when I'm debugging, it says buffer* = 0 ''. Does that mean it's empty? if so, why does it still send random numbers to my PLC?
  • 当我在调试的时候,当我的鼠标在我的缓冲区上时,它说缓冲区* = 0。这是否意味着它是空的?如果是这样,为什么它还会向我的PLC发送随机数呢?

1 个解决方案

#1


1  

Whats the difference between a byte* buffer;in C++ and a byte buffer[]; in C#?

在C++和字节缓冲之间的区别是什么?在c#中?

Assuming you have typedef unsigned char byte;:

假设您有typedef无符号char字节;

In C++/CLI, byte* buffer; declares a buffer variable which is a pointer to a byte. In C# you write it as: byte* buffer; in an unsafe context. The syntax is the same.

在c++ / CLI,字节*缓冲;声明一个缓冲区变量,它是一个指向字节的指针。在c#中,你把它写为:字节*缓冲区;在一个不安全的环境。语法是一样的。

In C#, byte[] buffer; declares a buffer variable which is a managed array of byte values. The C++/CLI syntax for this is array<byte> buffer;.

在c#中,byte[]缓冲区;声明一个缓冲区变量,它是一个管理的字节值数组。它的c++ /CLI语法是数组 缓冲区;

Note that byte buffer[N]; is C++ syntax for a native array, which is not the same thing. That one can decay to a byte* pointer.

注意,字节缓冲区[N];是一个本机数组的c++语法,这不是一回事。那个可以衰变为一个字节的指针。

Looks like your code uses a native memory buffer, but there's no way to tell that for sure without the source of ReadDB.

看起来您的代码使用了本机内存缓冲区,但是没有办法确定没有ReadDB的源代码。

When I mouse over on my buffer when I'm debugging, it says buffer* = 0 ''. Does that mean it's empty? if so, why does it still send random numbers to my PLC?

当我在调试的时候,当我的鼠标在我的缓冲区上时,它说缓冲区* = 0。这是否意味着它是空的?如果是这样,为什么它还会向我的PLC发送随机数呢?

It means the first byte in your buffer is 0. If your buffer is supposed to contain C string data, it means it contains the empty string.

这意味着缓冲区中的第一个字节为0。如果缓冲区应该包含C字符串数据,则意味着它包含空字符串。

Am I doing something wrong in with the buffer?

我是不是做错了什么?

Most probably. But I can't say exactly what's wrong, because you didn't post the source of ReadDB.

最有可能。但是我不能确切地说什么是错的,因为你没有发布ReadDB的源代码。

There are a couple of red flags though:

但是有一些危险信号:

  • What's the buffer size? Your code doesn't know what ReadDB returns, so how are you supposed to ensure you're not overflowing it?
  • 缓冲区的大小是什么?您的代码不知道ReadDB返回的是什么,那么您应该如何确保您没有溢出它呢?
  • Who's the owner of the buffer, meaning: who's supposed to free it? It presumably lives on the heap, so your code is leaking memory. If it lives on ReadDB's stack you have a memory corruption issue. Either way, this code is wrong.
  • 谁是缓冲区的所有者,意思是:谁应该释放它?它可能存在于堆中,所以您的代码正在泄漏内存。如果它生活在ReadDB的堆栈上,您就有一个内存损坏问题。无论哪种方式,这段代码都是错误的。

#1


1  

Whats the difference between a byte* buffer;in C++ and a byte buffer[]; in C#?

在C++和字节缓冲之间的区别是什么?在c#中?

Assuming you have typedef unsigned char byte;:

假设您有typedef无符号char字节;

In C++/CLI, byte* buffer; declares a buffer variable which is a pointer to a byte. In C# you write it as: byte* buffer; in an unsafe context. The syntax is the same.

在c++ / CLI,字节*缓冲;声明一个缓冲区变量,它是一个指向字节的指针。在c#中,你把它写为:字节*缓冲区;在一个不安全的环境。语法是一样的。

In C#, byte[] buffer; declares a buffer variable which is a managed array of byte values. The C++/CLI syntax for this is array<byte> buffer;.

在c#中,byte[]缓冲区;声明一个缓冲区变量,它是一个管理的字节值数组。它的c++ /CLI语法是数组 缓冲区;

Note that byte buffer[N]; is C++ syntax for a native array, which is not the same thing. That one can decay to a byte* pointer.

注意,字节缓冲区[N];是一个本机数组的c++语法,这不是一回事。那个可以衰变为一个字节的指针。

Looks like your code uses a native memory buffer, but there's no way to tell that for sure without the source of ReadDB.

看起来您的代码使用了本机内存缓冲区,但是没有办法确定没有ReadDB的源代码。

When I mouse over on my buffer when I'm debugging, it says buffer* = 0 ''. Does that mean it's empty? if so, why does it still send random numbers to my PLC?

当我在调试的时候,当我的鼠标在我的缓冲区上时,它说缓冲区* = 0。这是否意味着它是空的?如果是这样,为什么它还会向我的PLC发送随机数呢?

It means the first byte in your buffer is 0. If your buffer is supposed to contain C string data, it means it contains the empty string.

这意味着缓冲区中的第一个字节为0。如果缓冲区应该包含C字符串数据,则意味着它包含空字符串。

Am I doing something wrong in with the buffer?

我是不是做错了什么?

Most probably. But I can't say exactly what's wrong, because you didn't post the source of ReadDB.

最有可能。但是我不能确切地说什么是错的,因为你没有发布ReadDB的源代码。

There are a couple of red flags though:

但是有一些危险信号:

  • What's the buffer size? Your code doesn't know what ReadDB returns, so how are you supposed to ensure you're not overflowing it?
  • 缓冲区的大小是什么?您的代码不知道ReadDB返回的是什么,那么您应该如何确保您没有溢出它呢?
  • Who's the owner of the buffer, meaning: who's supposed to free it? It presumably lives on the heap, so your code is leaking memory. If it lives on ReadDB's stack you have a memory corruption issue. Either way, this code is wrong.
  • 谁是缓冲区的所有者,意思是:谁应该释放它?它可能存在于堆中,所以您的代码正在泄漏内存。如果它生活在ReadDB的堆栈上,您就有一个内存损坏问题。无论哪种方式,这段代码都是错误的。