2013-05-18 3 views
2

도움, 조언 또는 제안에 매우 감사드립니다. 동기 인터페이스를 사용하여 측지 도구를 제어하는 ​​응용 프로그램이 있습니다. 그러나 일부 명령은 그 특성상 비동기식입니다. GetReflectors. 이 명령을 실행하면 사용 가능한 반사기 수만큼의 서버 응답을받습니다. 그래서 나는 COM 이벤트를 등록하고 핸들러 함수를 연관시켰다. 여태까지는 그런대로 잘됐다. 나는 데이터를 표시 할 수 있지만 주 변수에 변수를 전달하는 방법을 모르겠습니다. 변수를 .mat 파일이나 .txt 파일로 저장하려고 시도했습니다. 사실 Matlab에서 작동하지만 컴파일 된 .exe 응용 프로그램에서는 작동하지 않습니다 (오류 발생 이벤트). 심지어 disp 명령은 컴파일 된 응용 프로그램에서 작동하지 않습니다 (아무 것도 표시하지 않음). 그래서 주된 질문은 핸들러에서 주요 기능으로 변수를 전달하는 방법입니다. 방법이 있습니까? 전역 변수? 고마워요 Filip이벤트 핸들러에서 변수 전달하기

편집 : 문제를 demostrate하는 코드를 추가하고 있습니다 ... 사용자가 하나를 선택할 수 있도록 (리플렉터가 여러 개 있기 때문에) 리플렉터 이름과 리플렉터 ID를 저장해야합니다.

function pushbutton_GetReflectors_Callback(hObject, eventdata, handles) 
ltsync = actxserver ('LTControl.LTCommandSync2');  %Act as server: LTConnect2 
ltsync.events()           %List of all COM events 
ltsync.registerevent({'ReflectorsData' 'ReflectorsHandler'}) %Register event 
ltsync.GetReflectors()        %Ask instrument for reflectors 
pause(3)             %Time to receive answers 
end 

function ReflectorsHandler(varargin) %Handler of the event ReflectorsData 
%var1,var2,reflectorID,reflectorName,var5,surfaceOffset,reflectorsTotal,var8,var9 
disp('Reflector Data:'); 
disp(varargin{3})  %Reflector ID 
disp(varargin{4})  %Reflector name 
end 
+0

이것은 순전히 MATLAB입니까? 그렇다면'event.EventData'에서 클래스를 파생시켜이 작업을 수행 할 수 있다고 생각합니다. 예제를 게시합니다. – wakjah

+0

예, 순수 MATLAB입니다. – flogs

답변

0

난 당신이 registerevent에 함수 핸들을 전달하는 대신 단지 문자열 함수 이름, 당신은 다시 데이터를 전달 할 수 있도록 클래스를 만들어이 문제를 해결할 수 있다고 생각합니다. 첫째, 클래스 :

classdef ReflectorsResponse < handle 
    properties (SetAccess = private) 
     reflectors 
     responseComplete = false; 
     reflectorsTotal = NaN; 
    end 

    methods 
     function respond(obj, varargin) 
      % Create a struct for each reflector (or you could define 
      % another class, but let's keep it simple for the time being) 
      newRefl = struct(); 
      newRefl.ID = varargin{3}; 
      newRefl.name = varargin{4}; 
      newRefl.surfaceOffset = varargin{6}; 
      % ... store other properties in struct 
      % Store this reflector 
      obj.reflectors = [obj.reflectors; newRefl]; 

      % Store total reflector count and check for completion 
      if isnan(obj.reflectorsTotal) 
       obj.reflectorsTotal = varargin{7}; 
      end 

      if length(obj.reflectors) == obj.reflectorsTotal 
       obj.responseComplete = true; 
      end 
     end 
    end 
end 

그런 다음 respond 방법 당신의 핸들러를 제작하여이를 사용할 수 있습니다 반사경의 각에 대한 응답, 수의 거기까지

function pushbutton_GetReflectors_Callback(hObject, eventdata, handles) 
    % Create the response object and associated handler function handle 
    response = ReflectorsResponse(); 
    handlerFun = @(varargin)response.respond(varargin{:}); 

    ltsync = actxserver ('LTControl.LTCommandSync2');  %Act as server: LTConnect2 
    ltsync.events()           %List of all COM events 
    ltsync.registerevent({'ReflectorsData' handlerFun}) %Register event 
    ltsync.GetReflectors()        %Ask instrument for reflectors 

    % Wait for request to complete 
    while ~response.responseComplete 
     pause(0.1); 
     drawnow update; 
     % NOTE: Should add a timeout to this loop 
    end 

    % Do stuff with response.reflectors 
end 

이 대기를 이는 제 1 응답으로부터 결정된다. while 루프에 시간 초과를 추가해야합니다. 그렇지 않으면 무한정 기다릴 위험이 있습니다.

처리해야하는 이러한 비동기 요청이 많은 경우 전체 요청/응답 시퀀스 (ActiveX 서버 만들기, 이벤트 처리기 설정 및 응답 대기 중 포함)를 캡슐화하는 것이 좋습니다.))를 생성하고, 각기 다른 요청에 대한 특정 하위 클래스를 파생시킵니다.

+0

감사합니다. 당신이 이해한다면 나는 확신하지 못합니다. LTControl.dll에 의해 정의되기 때문에 이벤트를 편집 할 수 없습니다. 따라서 핸들러의 입력은 계측기 응답에서만 제공됩니다. 위의 간결한 예제를 추가했습니다. – flogs

+0

@ user2397310 답변 됨; 잘하면이 작동하지만, 거기에 어떤 문제가 있다면 알려 주시기 바랍니다 - 분명히 나는 ​​그 COM 구성 요소 (또는 반사판)가 없어 완벽하게 그것을 테스트 할 수 없습니다. – wakjah

+0

위대한,이 아주 좋아 보인다. 불행하게도 나는 그것을 지금 시험 할 수 없다. 나는 금요일에 악기를 가지고있다. 내가 너를 실망 시키겠다. 고마워, 정말 고마워. – flogs

관련 문제