2

今書いた次の関数を使用して、文字列値をグローバルメモリハンドルに、またはその逆に変換したいと思います。

しかしStrToGlobalHandle()、私のテストプログラムがハングする原因になります。したがってGlobalHandleToStr()、まだテストできません。また、コードが論理的であるかどうかも疑問に思っています。

function StrToGlobalHandle(const aText: string): HGLOBAL;
var
  ptr: PChar;
begin
  Result := 0;
  if aText <> '' then
  begin
    Result := GlobalAlloc(GMEM_MOVEABLE or GMEM_ZEROINIT, length(aText) + 1);
    if Result <> 0 then
    begin
      ptr := GlobalLock(Result);
      if Assigned(ptr) then
      begin
        StrCopy(ptr, PChar(aText));
        GlobalUnlock(Result);
      end
    end;
  end;
end;

function GlobalHandleToStr(const aHandle: HGLOBAL): string;
var
  ptrSrc: PChar;
begin
  ptrSrc := GlobalLock(aHandle);
  if Assigned(ptrSrc) then
  begin
    SetLength(Result, Length(ptrSrc));
    StrCopy(PChar(Result), ptrSrc);
    GlobalUnlock(aHandle);
  end
end;

テストコード:

procedure TForm3.Button1Click(Sender: TObject);
var
  h: HGLOBAL;
  s: string;
  s2: string;
begin
  s := 'this is a test string';
  h := StrToGlobalHandle(s);
  s2 := GlobalHandleToStr(h);
  ShowMessage(s2);
  GlobalFree(h);
end;

ところで、私はこれら2つの関数をヘルパーとして使用して、プログラム間で文字列値を送信したいと思います。プロセスAからプロセスBにグローバルハンドルを送信し、プロセスBはを使用して文字列を取得しますGlobalHandleToStr()。ところで、私はWM_COPYや他のIPCメソッドを知っていますが、私の場合はこれらは適切ではありません。

4

3 に答える 3

6

Delphi 2010の文字列はユニコードであるため、適切なバッファサイズを割り当てていません。

この行を置き換えます

Result := GlobalAlloc(GMEM_MOVEABLE or GMEM_ZEROINIT, length(aText) + 1);

これとともに

Result := GlobalAlloc(GMEM_MOVEABLE or GMEM_ZEROINIT, (length(aText) + 1)* SizeOf(Char));
于 2012-09-26T15:40:18.580 に答える
3

を呼び出したときにプログラムがハングした場合は、プログラムの初期の段階でヒープが破損GlobalAllocしている可能性があります。それは未定義の振る舞いにつながります。関数は問題を検出してエラーを返す可能性があり、プログラムをクラッシュさせる可能性があり、メモリのさらに多くをサイレントに破損する可能性があり、ハングする可能性があります。

割り当てられたメモリの終わりを超えて呼び出しが書き込まれるため、そのヒープの破損は前の呼び出しから発生する可能性があります。バイトを割り当てていますが、関数は文字列内の文字数を返します。これは、文字の幅が1バイトの場合にのみ有効ですが、Delphi 2009の場合はそうではありません。乗算して、バイト数を取得します。StrToGlobalHandleStrCopyLengthSizeOf(Char)

Result := GlobalAlloc(GMEM_MOVEABLE or GMEM_ZEROINIT, SizeOf(Char) * (Length(aText) + 1));
于 2012-09-26T16:00:01.293 に答える
1

を使用してプログラム間でデータを送信することはできませんGlobalAlloc。16ビットWindowsでのみ機能しました。代わりにメモリマップトファイルを使用してください。

于 2012-09-26T15:55:03.913 に答える