C++ cli Snap7写入S7-1200 PLC

C++ cli Snap7写入S7-1200 PLC,c++-cli,plc,s7-1200,siemens,C++ Cli,Plc,S7 1200,Siemens,我正试图用C++/CLI应用程序为我的西门子公司写一些东西 读取正常(除了第一次读取时给出奇数值) 但是写作是做一些完全不同于我想要的事情 您可以在下面找到代码: private: void WriteSiemensDB() { byte* buffer; if (ConnectToSiemensPLC()) //Check if you are connected to PLC { String^ msg;

我正试图用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]);
    }
}
我实际上收到了消息“Gelukt”,但它仍然写入了rwong值。因此,填充我的
缓冲区时出现了一些问题。我的缓冲器有问题吗

在C#中,除了缓冲区是
字节缓冲区[]之外,我有相同类型的应用程序

我的问题是:

  • 字节*缓冲区之间有什么区别和<代码>字节缓冲区[];<代码>在C#中
  • 调试时,当我将鼠标移到缓冲区上时,它会显示
    buffer*=0'
    。这是否意味着它是空的?如果是这样,为什么它仍然向我的PLC发送随机数
字节*缓冲区之间有什么区别和<代码>字节缓冲区[];<代码>在C#中

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

在C++/CLI中,
byte*buffer
声明一个
缓冲区
变量,该变量是指向
字节的指针
。在C语言中,你把它写成:
byte*buffer
不安全的
上下文中。语法是相同的

在C#中,
字节[]缓冲区
声明一个
缓冲区
变量,该变量是
字节
值的托管数组。这方面的C++/CLI语法是
数组缓冲区

注意
字节缓冲区[N]是一个本地数组的C++语法,这不是一回事。它可以衰减为
字节*
指针

看起来您的代码使用了本机内存缓冲区,但如果没有
ReadDB
的源代码,就无法确定这一点

调试时,当我将鼠标移到缓冲区上时,它会显示
buffer*=0'
。这是否意味着它是空的?如果是这样,为什么它仍然向我的PLC发送随机数

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

我的缓冲器有问题吗

很可能。但是我不能说到底是什么问题,因为你没有发布
ReadDB
的源代码

不过,有几个危险信号:

  • 缓冲区大小是多少?您的代码不知道
    ReadDB
    返回什么,那么您应该如何确保不会溢出它
  • 谁是缓冲区的所有者,意思是:谁应该释放缓冲区?它可能存在于堆上,因此您的代码正在泄漏内存。如果它位于
    ReadDB
    的堆栈上,则存在内存损坏问题。不管怎样,这个代码都是错误的

是的,我注意到我必须将缓冲区更改为数组,我已经这样做了,现在问题解决了。谢谢你的信息!:)
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;
}