摘自《上海质子治疗装置注入器远程控制系统的构建》
EDM 和 MEDM安装哪个?
EDM 和 MEDM 是当前常见的 OPI 界面开发工具。 OPI 界面开发工具 EDM(Extensible Display Manager)是由美国橡树岭实验室(ORNL)主要承担开发的,通过 OPI 控制界面可以对 IOC 实时数据库里面的数据进行监测与控制。
基于图形用户界面 GUI(Graphical User Interface)的 MEDM(Motif Editor and Display Manager)也是一种图形化的 OPI 界面开发工具。早期在 EPICS 刚刚发展起来的时候,MEDM 广泛被世界各大实验室用来进行控制界面的开发。它的风格和功能和 EDM 大致一样,用其开发的控制系统在运行过程中也较为稳定,但它具有控件类型比较单一,且无法进行扩展的缺点。因现已经暂停了对 MEDM的开发,所有对于那些将要新建的加速器控制系统建议不要再使用 MEDM 进行控制界面的开发。
EDM 的安装,EDM 作为 EPICS 的一个扩展工具,在安装目录上有要求,需要在/usr/local/epics/extension/src 目录下创建目录 edm,然后把EDM的安装包解压到该文件夹下面,在安装之前也需要进行一些环境变量的配置,进入到/usr/local/epics/extensions/configure 目录下修改 RELEASE 文件,修改为EPICS_BASE=/usr/local/epics/base/,保存后退出。在编译之前,可以事先安装一些软件包以为在编译的时候报错进行多次编译,在 CentOS 下安装软件包的命令为 yum install packet,packet 为需要安装的软件包的包名,通常可能需要安装的是:gcc-c++、readline-devel、motif-devel、libXtst-devel 以及giflib-devel。还有需要的一些软件包根据在EDM编译时提示的错误再进行安装。EDM的编译,进入到/usr/local/epics/extension/src/edm 下,在终端运行 make,如无报错,则 EDM编译完成。
编译出现的错误
然后编译中出现错误如下图
然后查了一下,说是
const char*是不能直接赋值到char*的,这样编译都不能通过,理由:假如可以的话,
那么通过char*就可以修改const char指向的内容了,这是不允许的.
所以char*要另外开辟新的空间
怎么解决?
find -name 文件名 找到remFileOpen.cc
打开文件(vim ~/.vimrc,然后set nu 然后保存退出就可以永久显示行号辣,set nonu就是关闭行号)
我看到文件是这样的,
413 static int fileReadable (
414 char *fname )//定义了一个字符型指针
415 {
416
417 FILE *f;
418
419 char nameToCheck[255+1];//最大为256,不知道为啥要+1
420
421 int result, len1, len2, remain;
422
423 char *first, *last;
424
425 // if filename is of the form name[parm].ext,
426 // use name.ext in the "is readable check".
427 first = index( (const char *) fname, (int) '[' );
428 if ( first ) {
429 last = rindex( (const char *) fname, (int) ']' );
430 }
// 如果括号里为真,则执行last
// &位操作,&&逻辑与,条件满足则为真
431 if ( first && last && ( first < last ) ) {
// 这句是说,如果first,last存在,且first<last,则执行以下语句
432 len1 = (long) first - (long) fname;//[的地址与fname的地址差
433 if ( len1 > 255 ) len1 = 255;
//char *strncpy(char *dest, const char *src, int n),
//把src所指向的字符串中以src地址开始的前n个字节复制到dest所指的数组中,
//并返回被复制后的dest。
434 strncpy( nameToCheck, fname, len1 );//这里len1小于255
435 nameToCheck[len1] = 0;//这里取fname[前的字符串到nameToCheck,使得第len1-1个为0
436 remain = 255 - len1;//[之后的字符串的位数
//strlen所作的仅仅是一个计数器的工作,它从内存的某个位置(可以是字符串开头,中间某个
//位 置,甚至是某个不确定的内存区域)开始扫描,直到碰到第一个字符串结束符'\0'为止,然
//后返回计数器值(长度不包含'\0')。
437 len2 = strlen( fname ) - (long) last + (long) fname - 1;
438 if ( len2 > remain ) len2 = remain;
439 strncat( nameToCheck, last+1, len2 );
//函数原型:extern char *strcat(char *dest,char *src);
//功能:把src所指字符串添加到dest结尾处(覆盖dest结尾处的'\0')并添加'\0'。
440 nameToCheck[len1+len2] = 0;
441 }
//这个if里的作用就是把[]里的内容去掉,剩下的内容拼到一起
442 else {
443
444 strncpy( nameToCheck, fname, 255 );
445 nameToCheck[255] = 0;
446
447 // else if filename is of the form name.ext?params,
448 // use name.ext in the "is readable check".
449 first = index( (const char *) nameToCheck, (int) '?' );
450 if ( first ) {
451 *first = (char) 0;
452 }
453
454 // else use fname without any changes
根本看不懂这个函数是干啥的,于是开始百度。
首先,index函数和rindex函数
char * index(const char *s, int c);
char * rindex(const char *s, int c);
函数说明:index()用来找出参数s 字符串中第一个出现的参数c 地址,然后将该字符出现的地址返回。字符串结束字符(NULL)也视为字符串一部分。
返回值:如果找到指定的字符则返回该字符所在地址,否则返回0.
函数说明:rindex()用来找出参数s 字符串中最后一个出现的参数c 地址,然后将该字符出现的地址返回。字符串结束字符(NULL)也视为字符串一部分。
返回值:如果找到指定的字符则返回该字符所在的地址,否则返回0。
file *fp
FILE *fp
//FILE是在C标准库中(stdio.h)中定义的一个结构体,通常用指针的方式保存在内存中,其内容描述了一个
//文件,或者说”流“更恰当。
//标准库中提供了通用的函数来读取和写入流,如fopen,fclose等等
//FILE指针的使用在C中很广泛,如一些常用的输入/出流就是FILE*的类型,如
//stdin、stdout、stderr等
//当然,C++中用类进行了封装,更加具体和方便。
//综上,FILE*fp就是声明了一个类型为FILE的,名为fp的指针(fp指file pointer, 文件指针),用于保存
//流信息
所以这里的问题就是,一开始定义的是char *fname,char nametocheck[],后面用的时候如first里
first= index((const char*)fname,(int)‘[’),把const char*的指针传给first,是char*,所以要把const char*转换为char*
怎么转呢?https://blog.csdn.net/hebbely/article/details/79577880
const char*转换为char*
#include "stdafx.h"
#include <iostream>
int _tmain(intargc, _TCHAR* argv[])
{
const char* constc = "Hello World!"; //初始化const char* 类型
char* c = nullptr; //初始化char*类型
c= const_cast<char*>(constc); //const char*类型转char*类型
printf_s("%s\n", constc); //打印const char* 类型数据
printf_s("%s\n", c); //打印char*类型数据
return 0;
}
然后又出现缺gif_lib.h文件的错误
这里的.h文件是什么呢?C语言和C++语言的头文件
我们一般在.h类的头文件里面只放入函数声明,宏定义,函数原型。
而具体的实现在.cpp文件里面
比如你在<math.h>里面看到的数学函数都只有声明
具体实现在<math.cpp>里面
在编译的时候,编译器会自动加载和.h匹配的.CPP文件。
然后下载gif_lib.h文件,http://rpmfind.net/linux/rpm2html/search.php?query=/usr/include/gif_lib.h
用yum localinstall ****安装
安装之后有出现错误,zlibversion 没有声明,是在文件的开头没有调用zlib的头文件,加上#include <zlib.h> #include <zconf.h>就行了
在终端运行 make,如无报错,则 EDM编译完成。EDM 和 EPICS BASE 以及 EPICS Extensions 不一样,安装完之后还需要进行一些必要的配置才能正常使用。在终端上输入
cd /usr/local/epics/extensions/src/edm/setup,
接着输入
export HOST_ARCH=linux-x86_64,
再输入 source setup.sh。配置完上面一步之后,安装先前配置 EPICS BASE 的环境变量一样,打开.bashrc 文件。添加一下内容
EDMOBJECTS=/usr/local/epics/extensions/src/edm/setup
EDMHELPFILES=/usr/local/epics/extensions/src/edm/helpFiles
EDMBASE=/usr/local/epics/extensions/src/edm
EDMPVOBJECTS=/usr/local/epics/extensions/src/edm/setup
EDMFILES=/usr/local/epics/extensions/src/edm/setup
EDMDATAFILES=:~/.
EDMWEBBROWSER=firefox
配置完之后,正常情况下就可以使用 EDM 了