分享

WINCC脚本字符串处理总结

 紫殿 2013-02-01
组态注意事项: 下面说明了关于在C脚本中处理字符串时最重要的问题。必须考虑性能和稳定性因素。在不一致时,内存区可能被覆写,从而使系统锁死 。最坏的情况出现在字符指针。如果指针设计不当,内存区可能被覆写。下面是有关错误和正确组态的四个样例。 

没有预留内存区: char *a; a=GetTagChar("Tag name"); strcat(a,"xyz"); //有一个连接到文本的指针“a” //没有预留内存区

  • 正确: 通过查询有效的指针将字符串正确复制到预定义的缓冲器中(来自描述WinCC信息系统的样例):  
  •  char* pszValue = NULL; 
  •  char szValue[101]; 
  •  pszValue = GetTagChar("Varname"); //读标签值并将其缓存到pszValue。/*如果返回一个有效值,将该函数返回值存入局部字符串szValue中。最多保存100个字符。*/
  •  if(pszValue !=NULL) //!=NULL是必须执行的检查 //以便保证没有NULL指针提交 
  • strncpy(szValue,pszValue,100); … 
  • }
  •   else 
  • printf("Pointer invalid\r\n"); //使用了无效值
  • }
 
没有预留足够的内存区: 通常,由于预留的内存区太小导致内存被覆写。在这些情况下,通常在C中进行字符串处理时,文本结尾的一个附加字符必须始终被保留。也就是说,必须要比被处理的文本长度多预留出一个字符。

  • 错误: char a[4]; strcpy(a,"1234"); //总是有4个字符被复制到一个4字符的数组中; // 错误:文本的结尾字符被遗漏  
  • 正确: char a[5]; //内存区的大小必须 //总是比被复制的文本多一个字符 strcpy(a,"1234");

字符*作为项目函数的返回值无效: 如果在项目函数中返回“char*”,必须用“SysMalloc”预留相应的内存区。如果内存区是通过字符…[x]预留的,像“错误”例子中所描述那样,那么当 退出项目函数时内存区将立刻被释放,因此在进行进一步的动作处理时将传递的是无效的值。

  • 错误:
  •  char* new_function_1()
  •  { 
  • char myString[100]; 
  • sprintf(myString,"VarName%d", GetTagWord("processvariable"));
  •  return myString;
  • }
  • 正确:
  •  char* new_function_1() 
  • char* myString; 
  • myString = SysMalloc(100); 
  • sprintf(myString,"VarName%d", GetTagWord("processvariable"));
  •  return myString;
  •  }

没有Null指针检索的无效字符串拷贝(导致日志文件 - WinCC_Sys_xx.LOG中的“ExecuteError in Action” ) 当动作在执行并且图像被取消选定(目标未发现)时此条目出现在WinCC_Sys.Log中

  • 错误: 
  • char sign[5];
  •  strcpy(sign,GetText(lpszPictureName,lpszObjectName)); 
  • if (0==strcmp(sign,"+")) 
  • {
  •  SetText(lpszPictureName,lpszObjectName,"-"); 
  • SetVisible(lpszPictureName,"B5",TRUE);
  •  }
  •  else
  •  { 
  • SetText(lpszPictureName,lpszObjectName,"+");
  •  SetVisible(lpszPictureName,"B5",FALSE);
  •  }

为了避免无意的复制太多的字符到“sign” (例如在后来作改动时) ,并为了避免当取消选定图像时由于“strcpy()”导致的异常,在“strncpy()”复制到Null-指针之前应该使用和检查“strncpy()” 。

  • 正确: 
  • char sign[5], *myPointer; 
  • myPointer = GetText(lpszPictureName,lpszObjectName);
  •  if(myPointer != NULL)
  •  { 
  • strncpy(sign, myPointer, 4); 
  • if (0==strcmp(sign,"+"))
  •  { 
  • SetText(lpszPictureName,lpszObjectName,"-");
  •  SetVisible(lpszPictureName,"B5",TRUE);
  •  } 
  • else
  •  { 
  • SetText(lpszPictureName,lpszObjectName,"+");
  •  SetVisible(lpszPictureName,"B5",FALSE);
  •  }
  •  }
  •  else
  •  { 
  • printf("Error in GetText() !\r\n");
  •  }

警告: 函数strcpy()将“Source”指针所指向的包含末尾字符'\0’的字符串复制到“Target”指针指向的位置。字符串不能 重叠,并且目标必须足够大 (源字符串长度 + 1,因为有'\0’)。函数strncpy()除了仅复制起始的n个字节外其余与函数strcpy()相同。如果起始的n个字节中没有'\0’,结果将不是以'\0’结束。这将导致未定义的系统状态。



用strcat函数来连接字符串。
假设有四个变量tag1,tag2,tag3,tag4都是8位文本字符变量。把tag1~tag3连接起来显示在tag4中。测试:先建立这四个变量,然后在wincc的画面中建立四个输入输出域,分别连接tag1~tag4,建立一个按钮,在按钮的c动作中:
char buffer[256]="";
strcat(buffer,GetTagChar("tag1"));
strcat(buffer,GetTagChar("tag2"));
strcat(buffer,GetTagChar("tag3"));
SetTagChar("tag4",buffer);

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多