2016-08-22 2 views
0

C++에서 CLIPS deffunction을 호출하고 인스턴스를 전달하고 싶습니다. 표준 CLIPS 6.30 배포판 (C++ 바인딩이 아님)을 사용하고 있습니다. 저는 현재 다음과 같은 정의를하고 있어요 : EnvFunctionCall 인스턴스 주소를 C/C++에서 전달

(defclass CFAM (is-a USER)) 

(deffunction drop-cfam (?cfam) 
    (send ?cfam delete)) 

(definstances KNOWN_THINGS 
    (cfam-1 of CFAM)) 

나는 C에서 함수 drop-cfam를 호출 ++ I 삭제할 예를 들어 그것을 인스턴스 주소를 전달하여.

Calling 'EnvFunctionCall for 'drop-cfam' w/ args: 0x274c290 
[MSGFUN1] No applicable primary message-handlers found for delete. 
[PRCCODE4] Execution halted during the actions of deffunction drop-cfam. 

처음이 나를 통과 할 (내가 믿는 것은)을 위해 아마도 그것은 인스턴스 잘못된 것을 제안 : 터미널 창에 표시하는 동안이 중단

void* instancePtr = EnvFindInstance(clipsEnv,NULL,"cfam-1",false); 
assert(EnvValidInstanceAddress(clipsEnv,instancePtr)); 

ostringstream args; 
args << instancePtr; 

cout << "Calling 'EnvFunctionCall for 'drop-cfam' w/ args: "<< args.str() << endl; 

DATA_OBJECT callResult; 
const bool callFailed = EnvFunctionCall(clipsEnv,"drop-cfam",args.str().c_str(),&callResult); 
assert(!callFailed); // results in abort 

const bool droppedCfam = static_cast<bool>(DOToInteger(callResult)); 
assert(droppedCfam); 

는, 지정된 행에 발생 주소는 drop-cfam입니다.

CLIPS> (reset) 
CLIPS> (instances) 
[initial-object] of INITIAL-OBJECT 
[cfam-1] of CFAM 
For a total of 2 instances. 
CLIPS> (drop-cfam (instance-address [cfam-1])) 
TRUE 
CLIPS> (instances) 
[initial-object] of INITIAL-OBJECT 
For a total of 1 instance. 

고급 프로그래밍 가이드 (v6.30)를 인수 문자열로 EnvFunctionCall에 전달해야한다고 주장한다 : 그러나, 터미널에서 시험이이 문제가되지 않습니다 것을 의미한다. 이 절 (4.1.10)은 EnvFunctionCall에 전달 된 데이터 형식에 대한 제한을 지정하지 않으며 데이터 형식에 대한 어휘 양식을 지정하는 다른 원본을 참조하지 않습니다. 심지어 EnvFunctionCall을 통해 인스턴스 주소를 전달하거나 내 디자인을 수정해야하는 경우이를 피할 수 있는지 확실하지 않습니다.

EDIT/해결

나는 그것을하지 않았다 때 내 시스템 인스턴스 주소를 요구한다고 가정 내 디자인에 문제가 발생했습니다. 다음과 같이이 질문의 원하는 동작은 오히려 주소보다 EnvFunctionCall에 인스턴스 이름을 전달함으로써 달성 될 수있다 :

동일한 동작이
EnvFunctionCall(clipsEnv,"drop-cfam","[cfam-1]",&callResult); 

:

CLIPS> (reset) 
CLIPS> (drop-cfam [cfam-1]) 
TRUE 

난 아직 어떤 대답을 수락를 어휘 양식으로 인스턴스 주소를 전달하는 방법을 보여 주거나 터미널 버전이 인스턴스 이름과 인스턴스 주소를 모두 허용하는 이유를 설명합니다.

답변

0

C 포인터 (인스턴스, 사실 및 외부 주소 포함)에 대한 어휘 표현이 없으므로이를 직접 지정할 수 없습니다. 이는 터미널 명령 및 CLIPS 코드뿐 아니라 문자열 인수를 구문 분석하는 API 호출에 모두 적용됩니다. 실행 중 주소는 동적으로 바인딩되거나 함수 호출에서 반환 될 수 있으며 이러한 값은 함수에 전달 될 수 있습니다. 인스턴스 주소는 예제 함수 호출 "(drop-cfam (instance-address [cfam-1]))"의 터미널에서 계산됩니다. EnvFunctionCall 대신 EnvEval을 사용하여 동일한 유형의 표현식을 평가할 수 있습니다.

EnvEval(clipsEnv,"(drop-cfam (instance-address [cfam-1]))",&callResult);