2

我将非常感谢您的帮助、建议或建议。我有一个使用同步接口控制大地测量仪器的应用程序。但是,某些命令本质上是异步的,例如GetReflectors. 触发此命令后,我会收到与可用反射器数量一样多的服务器答案。所以我注册了一个 COM 事件并关联处理函数。到目前为止,一切都很好。我可以显示即将到来的数据,但我不知道如何将一些变量传递给主函数。我试图将变量保存为 .mat 文件或 .txt 文件并读取它。实际上它在 Matlab 中工作,但在编译的 .exe 应用程序中不起作用(错误触发事件)。甚至disp命令在已编译的应用程序中不起作用(不显示任何内容)。所以主要问题是:如何将变量从处理程序传递到主函数。有办法吗?全局变量?谢谢菲利普

编辑:我正在添加一个代码来演示这个问题......我需要保存反射器名称和反射器 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
4

1 回答 1

0

I believe you can solve this problem by passing a function handle to registerevent instead of just the string function name, and creating a class to allow you to pass the data back. First, the class:

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

You can then use this by making the respond method your handler:

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

This will wait until there has been a response for each of the reflectors, the number of which is determined from the first response. Note that you should add a timeout to the while loop, otherwise you risk waiting infinitely.

If there are lots of these asynchronous requests that you have to handle, I would suggest encapsulating the entire request/response sequence (including the creation of the ActiveX server, setup of the event handler, and waiting for the response(s)) in a generalised base class, and deriving specific subclasses for each different request.

于 2013-05-18T22:04:35.867 回答