NS2 시작 자습서-Tcl 클래스
Tcl 클래스는 다음과 같은 방법을 제공합니다.
Tcl 객체에 대한 참조 가져오기
이 클래스의 단일 인스턴스는 ~tclcl/Tcl에 있습니다.cc에서 정적 구성원 변수로 성명하기;
우리는 이 실례에 대한 인용을 받아야만 이 절에서 기술한 다른 방법에 접근할 수 있다.
이 인스턴스에 액세스하는 데 필요한 문은 다음과 같습니다.
Tcl& tcl = Tcl::instance();
OTcl 함수를 호출하여 해석기를 통해
인스턴스 tcl을 통해 OTcl 명령을 호출하는 방법에는 네 가지가 있습니다.그것들의 매개 변수는 기본적으로 다르다.
모든 함수는 하나의 문자열을 해석기에 전달하고 전체 상하문에서 문자열의 의미를 평가한다.
void Tcl::evalc(const char* s)
{
unsigned int n = strlen(s) + 1;
if (n < sizeof(buffer_) - (bp_ - buffer_)) {
char* const p = bp_;
bp_ += n;
strcpy(p, s);
eval(p);
bp_ = p;
} else {
char* p = new char[n + 1];
strcpy(p, s);
eval(p);
delete[] p;
}
}
void Tcl::eval(char* s)
{
int st = Tcl_GlobalEval(tcl_, s);
if (st != TCL_OK) {
int n = strlen(application_) + strlen(s);
if (n > MAX_CODE_TO_DUMP) {
s = "
[code omitted because of length]
";
n = strlen(application_) + strlen(s);
};
char* wrk = new char[n + 80];
sprintf(wrk, "tkerror {%s: %s}", application_, s);
if (Tcl_GlobalEval(tcl_, wrk) != TCL_OK) {
fprintf(stderr, "%s: tcl error on eval of: %s
",
application_, s);
exit(1);
}
delete[] wrk;
//exit(1);
}
}
void Tcl::eval()
{
char* p = bp_;
bp_ = p + strlen(p) + 1;
/*XXX*/
if (bp_ >= &buffer_[1024]) {
fprintf(stderr, "bailing in Tcl::eval
");
assert(0);
exit(1);
}
eval(p);
bp_ = p;
}
/*
* , 4 , evalf, Tcl.cc ,
* , ,
*
*/
다음 예제에서는 이러한 함수를 호출합니다.
Tcl& tcl = Tcl::instance();
char wrk[128];
strcpy(wrk, "Simulator set NumberInterfaces_ 1");
tcl.eval(wrk);
sprintf(tcl.buffer(), "Agent/SRM set requestFunction_ %s", "Fixed");
tcl.eval();
tcl.evalc("puts stdout {hello world}");
tcl.evalf("%s request %d %d", name_, sender, msgid);
해석기에 값을 얻거나 전달합니다
해석기가 C++ 방법을 호출할 때, 결과를 개인 구성원 변수 tcl ->로 되돌려줍니다result에 있습니다.
이 변수를 설정하는 데 두 가지 방법이 있습니다.(to)
void result(Tcl_Obj *pObj) {
Tcl_SetObjResult(tcl_, pObj);
}
inline const char* result() const {
return (char *) Tcl_GetStringResult(tcl_);
}
inline char* result() const {
return (tcl_->result);
}
inline void result(const char* p) {
tcl_->result = (char*)p;
}
void resultf(const char* fmt, ...);
/*examples*/
if (strcmp(argv[1], "now") == 0) {
tcl.resultf("%.17g", clock());
return TCL_OK;
}
tcl.result("Invalid operation specified");
return TCL_ERROR;
마찬가지로, C++ 방법이 OTcl 명령을 호출할 때, 해석기는 tcl ->result에서 결과를 되돌려줍니다.(from)
tcl.evalc("Simulator set NumberInterfaces_");
char* ni = tcl.result();
if (atoi(ni) != 1)
tcl.evalc("Simulator set NumberInterfaces_ 1");
오류 보고 및 일관된 방식으로 종료
이 방법은 컴파일된 코드의 오류를 보고하는 통일된 방법을 제공했다.
void Tcl::error(const char* s)
{
if (strlen(s) > MAX_CODE_TO_DUMP) {
s = "
[code omitted because of length]
";
};
fprintf(stderr, "%s: \"%s\": %s
", application_, s, tcl_->result);
exit(1);
}
/* example */
tcl.resultf("cmd = %s", cmd);
tcl.error("invalid command specified");
주의: Tcl::result와 Tcl:::error를 호출하는 것은 약간의 차이가 있습니다. 리셋 오류를 호출하면 해석기가 이상을 포착하고, 동시에 창고의 추적을 되돌려줍니다. 오류를 수정하기 위해 디버깅을 할 수 있지만, error를 사용하면 창고의 추적을 되돌려주지 않습니다.
TclObjects 저장 및 찾기
NS2는 컴파일 계층의 각 TclObject에 대한 참조를 해시 테이블에 저장합니다.이렇게 하면 객체에 빠르게 액세스할 수 있습니다.
해시표는 해석기의 내부다.NS2는 TclObject의 이름을 키로 사용하여 해시 테이블에 입력하고 TclObject를 찾거나 삭제합니다.
void Tcl::enter(TclObject* o)
{
int nw;
Tcl_HashEntry* he = Tcl_CreateHashEntry(&objs_, (char*)o->name(),
(int*)&nw);
Tcl_SetHashValue(he, (char*)o);
}
/*
* insert a pointer to the TclObject into hashtable
*/
TclObject* Tcl::lookup(const char* name)
{
/*XXX use tcl hash table */
Tcl_HashEntry* he = Tcl_FindHashEntry(&objs_, (char*)name);
if (he != 0)
return ((TclObject*)Tcl_GetHashValue(he));
return (0);
}
/*
* retrieve the TclObject with the name
*/
void Tcl::remove(TclObject* o)
{
Tcl_HashEntry* he = Tcl_FindHashEntry(&objs_, (char*)o->name());
if (he == 0)
abort();
Tcl_DeleteHashEntry(he);
}
/*
* delete references to the TclObject from the hash table
*/
이러한 함수는 클래스 TclObject와 클래스 TclClass가 내부에서 사용합니다.
해석기에 대한 직접 접근 얻기
만약 위의 방법이 부족하다면, 우리는 해석기의 핸들을 가져와, 우리의 함수를 작성해야 한다.
inline Tcl_Interp* interp() const { return (tcl_); }
/*
* returns the handle to the interpreter that is stored within the class Tcl.
*/
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.