1

TThreadList のコンテンツが Thread で失われているように見えるという問題がありました。

「PConnect」クラスに次の変数を作成します。

var mCustomfunctionCallbackThread: CustomfunctionCallbackThread; 

そして、次のようなグローバル変数:

var mCustomfunctionCallbackThreadList: TThreadList; 

次のように、「PConnect」クラスにこの変数を入力しています。

function PConnect.callCustomfunction(plugin, method: PAnsiChar; param :CustomParam; callback: ICustomfunctionCallback; callId: PAnsiChar): integer;
var paramName: PAnsiChar;
var id: PAnsiChar;
var error: integer;
var callbackList: TList;
var customfunctionCallback : ^CustomfunctionCallbackObject;
begin
     callbackList:= mCustomfunctionCallbackThreadList.LockList;

     new (customfunctionCallback);
     customfunctionCallback.callId:= id;
     customfunctionCallback.callbackMethod:= callback;
     callbackList.Add(customfunctionCallback);

     mCustomfunctionCallbackThreadList.UnlockList;
     exit(0);
end; 

Callback を受け取った後、次の関数が呼び出されます。この関数は、欠落しているその他のデータを TThreadList エントリに追加し、その後スレッドを開始する必要があります。

procedure PConnect.customfunctionCallbackReceived(param :CustomParam; callId: PAnsiChar; error: integer);
var customfunctionCallbackList: TList;
var it: TListEnumerator;
var callbackObject: ^CustomfunctionCallbackObject;
begin
    customfunctionCallbackList:= mCustomfunctionCallbackThreadList.LockList;
    it:= customfunctionCallbackList.GetEnumerator;
    while(it.MoveNext) do
    begin
        callbackObject:= it.GetCurrent;
        if strcomp(callbackObject.callId,callId) = 0 then
        begin
            callbackObject.param:= param;
            callbackObject.error:= error;
            break;
        end;
    end;
    mCustomfunctionCallbackThreadList.UnlockList;
    mCustomfunctionCallbackThread.Start();
end;  

Thread の Execute メソッドは、TThreadList のコンテンツを取得し、そのパラメータを使用して関数を呼び出す必要があります。

procedure CustomfunctionCallbackThread.Execute;
var callback: ICustomfunctionCallback;
var customfunctionCallbackList: TList;
var it: TListEnumerator;
var callbackObject: ^CustomfunctionCallbackObject;
var param: CustomParam;
var callId: PAnsiChar;
var error: Integer;
begin
    customfunctionCallbackList:= mCustomfunctionCallbackThreadList.LockList;
    it:= customfunctionCallbackList.GetEnumerator;
    while(it.MoveNext) do
    begin
        callbackObject:= it.GetCurrent;
        if callbackObject.error <> NULL then
        begin
            callback:= callbackObject.callbackMethod;
            param:= callbackObject.param;
            error:= callbackObject.error;
            callId:= callbackObject.callId;

            callback.callCustomfunctionCallback(param, callId, error);
            customfunctionCallbackList.Remove(callbackObject);
            break;
        end;
    end;
    mCustomfunctionCallbackThreadList.UnlockList;
end; 

そして、問題は次のとおりです。次の変数がゴミまたは Null ポインターを取得しました。

param:= callbackObject.param;
error:= callbackObject.error;
callId:= callbackObject.callId;

十分に説明されていることを願っています:)

私はいくつかの助けに満足しています:)

4

1 に答える 1

0

あなたがするとき

customfunctionCallback.callId:= id

変数idは初期化されていません。つまり、後で確認するときに

strcomp(callbackObject.callId,callId) = 0

初期化されていないため、その動作は明確に定義されてcallbackObject.callIdいません。次に何が起こるかというと、あなたが見る不明確な振る舞いは、式が決して評価されないので、またはフィールドTrueに割り当てることは決してないということです。これはあなたの観察と一致しています。paramerror

変数にして、に渡されたパラメータの値をコピーする必要があると思いcallIdます。しかし、私はあなたがしていることのすべての詳細を知らないので、私はそれを100%確信することはできません。stringcallIdPConnect.callCustomfunction

他のいくつかのコメント:

  • あなたは本当にあなたのクラスに名前を付けるつもりPConnectですか?通常、クラスの前に。を付けTます。
  • for inループの代わりにループを使用すると、コードがはるかに読みやすくなりwhileます。
  • Removeリストにへの呼び出しを含むループは非効率的です。あなたはすでにアイテムを見つけました、そして呼び出すことはRemoveただもう一度リストを検索します。そのループを行う方法はfor、インデックスを使用するクラスループを使用することです。そして、削除するアイテムを見つけたらDelete、アイテムのインデックスを渡すことを呼び出します。
  • アイテムを削除すると、呼び出しに失敗しますDispose。これは、メモリがリークすることを意味します。
于 2013-03-08T11:02:38.577 に答える