2016-07-30 3 views
2


Delphi 2010で、IStringsを使用してMemo1.Lines(TStringsとして)をテストサーバーのプロパティとして渡すDCOMクライアント/サーバーを作成したいとします。サーバーにはTMemoコンポーネントがあり、サーバーのIMemoIntfを通じてMemo1.Linesプロパティを設定または取得したいとします。

1-In RIDLエディタのIStringsはデフォルトのDelphi 2010では使用できませんでした。まずstdvcl40.dllを登録し、エディタの "uses"部分に追加してIStrings型のプロパティを追加できるようにしました。

IFontとIStringsをDelphi 2010で使用するには?

procedure TMemoIntf.Set_Text(const Value: IStrings); 
begin 
    SetOleStrings(Form1.GetText, Value); 
end; 


function TMemoIntf.Get_Text: IStrings; 
begin 
    GetOleStrings(Form1.GetText, Result); 
end; 

IMemoIntfがTMemoIntfによって実装されているインターフェースである次のよう

2-そしてIは、セットとサーバのMemo1.Linesを取得するための2つの機能Set_TextとGET_TEXTを実施しました。これは次のように自動的に定義されています

// *********************************************************************// 
// Interface: IMemoIntf 
// Flags:  (4416) Dual OleAutomation Dispatchable 
// GUID:  {2B6BD766-5FB6-413F-B8E2-4AB05D87E669} 
// *********************************************************************// 
    IMemoIntf = interface(IDispatch) 
    ['{2B6BD766-5FB6-413F-B8E2-4AB05D87E669}'] 
    function Get_Text: IStrings; safecall; 
    procedure Set_Text(const Value: IStrings); safecall; 
    property Text: IStrings read Get_Text write Set_Text; 
    end; 

そしてTMemoIntf次のように:

TMemoIntf = class(TAutoObject, IMemoIntf) 
protected 
    function Get_Text: IStrings; safecall; 
    procedure Set_Text(const Value: IStrings); safecall; 
end; 

クライアントに、私はすべてがうまく、正常に動作していfMemo.Set_Text呼び出し、およびクライアントは、サーバMEMO1の内容を設定すると私自身fMemo.Get_Textを呼び出すと、サーバーMemo1の内容を取得するために、次のエラーメッセージが表示されます。

Access violation at address ... in module 'combase.dll'.Read of address ...

クライアントは、サーバーとセット/ GET_TEXT呼び出しの結果を表示するために使用されMEMO1を示しプライベートフィールドfMemoを持っています。

TForm2 = class(TForm) 
... 
    btnSetText: TButton; 
... 
    btnGetText: TButton; 
    Memo1: TMemo; 
... 
    procedure btnSetTextClick(Sender: TObject); 
... 
    procedure btnGetTextClick(Sender: TObject); 
private 
    fMemo : IMemoIntf; 
end; 

// it gives me the error 
procedure TForm2.btnGetTextClick(Sender: TObject); 
var 
    Strings : IStrings; 
begin 
    Strings := fMemo.Get_Text; 
    SetOleStrings(Memo1.Lines, Strings); 
end; 

// it works fine 
procedure TForm2.btnSetTextClick(Sender: TObject); 
var 
    Strings : IStrings; 
begin 
    GetOleStrings(Memo1.Lines, Strings); 
    fMemo.Set_Text(Strings); 
end; 

同じことがIFontに適用さだと思うが、私はのTFontとTColorので動作するように同じものを実装する際にOLE_COLORが完璧に働いている(私はOLE_COLORが自動整列化タイプとして直接サポート、および2とは異なりされて知っています)。

私は間違っているのですか、それともDelphi 2010の何かですか?
IFontとIStringsでDelphi 2010の問題を緩和するにはどうすればよいですか?

+0

上記の問題は、Windows 10-Pro 64bitで "combase.dll"というエラーが発生したためにテストされました。 Windows 7-Ultimate 32ビットでは、「ole32.dll」にエラーが発生します。このテストでも "stdvcl40.dll"を登録する必要があります。 – Zonouzi

+0

私は新しいインターフェイスのGet/Set関数で "IStrings"を "TStrings.Text"に置き換え、COMでサポートされているようにBSTRを使用しました。これは回避策であり、緩和ではありません。理由を見つけることは、 "IFont"にとっても役立つはずです。 Delphi 2010のために特別に書かれたマーシャリングをカスタマイズするための優れたリファレンスを誰かが知っていますか?私は新しい "IString"と "IFont"の置き換えを実装しようとしています。または、ソースコードを調べて、この問題の原因を突き止めている可能性があります。 – Zonouzi

+0

こんにちはDavid、私の質問や私に何か問題がありますか?私は私の質問に対して何の答えもコメントもしていませんでした。それは普通ですか?それとも、ヒットするために何かする必要がありますか?前もって感謝します。 – Zonouzi

答えて

0

私が間違っていたことを発見しました。それは私です。

".ridl"ファイルの定義は非常に重要です。 "ゲッター関数"の場合、 "out"パラメーターは "IStrings **"でなければならず、 "putter function"では "IStrings *"でなければなりません。コンパイラは自動的に "TLB"ファイルを更新し、インターフェース定義にプロパティを追加し、 "IMemoIntf"の以前の実装では、すべてが両方向にうまく行きます。

私はこれがあなたに役立つことを願っています。誰かが私に何をしたかを見るために、完全なプロジェクトを追加する方法を私に見せてくれれば、追加する方法はわかりません。

関連する問題