Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Общие вопросы Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме 85 тыс рублей в месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 25.01.2012, 16:35   #1
iCaesy
In progress...
Форумчанин
 
Регистрация: 25.09.2011
Сообщений: 161
По умолчанию String и PChar

Вобщем суть в том что нужно из одно приложения в другое передать строку с помощью создания подгрузки файла в память, FileMapping.
Саму прогу написал, но строку не передает, точней передает иероглифы, в чем ошибка ?
Вот листинг:

Клиент:
Код:
unit cliUnit;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  Buttons, ExtCtrls, StdCtrls;

type
  TClientForm = class(TForm)
    TimeSpeedButton: TSpeedButton;
    MemSpeedButton: TSpeedButton;
    Timer1: TTimer;
    procedure FormCreate(Sender: TObject);
    procedure Timer1Timer(Sender: TObject);
    procedure TimeSpeedButtonClick(Sender: TObject);
    procedure MemSpeedButtonClick(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  ClientForm: TClientForm;
  hFileMapObj: THandle;
  pSharedBuf:  Pointer;
  win: PChar;
implementation

{$R *.DFM}
type
 pDataRecord = ^TDataRecord;
 TDataRecord = record
  DateTime : PChar;
  Mem : PChar;
  end;


procedure TClientForm.FormCreate(Sender: TObject);
begin
 hFileMapObj:=
   CreateFileMapping(MAXDWORD, nil, PAGE_READWRITE, 0, 50, '_SharedMem');
  if  (hFileMapObj=0) then
   begin ShowMessage('Cannot CreateFileMapping'); Application.Terminate; Exit; end;
  pSharedBuf :=
    MapViewOfFile(hFileMapObj, FILE_MAP_WRITE, 0, 0, 0);
  if (pSharedBuf = nil) then
   begin ShowMessage('Cannot MapViewOfFile'); Application.Terminate; end;
end;

procedure TClientForm.Timer1Timer(Sender: TObject);
var p: integer;
begin
 if MemSpeedButton.Down then MemSpeedButton.Caption := PChar(pDataRecord(pSharedBuf)^.Mem);
 if TimeSpeedButton.Down then TimeSpeedButton.Caption := PChar(pDataRecord(pSharedBuf)^.DateTime);
end;

procedure TClientForm.TimeSpeedButtonClick(Sender: TObject);
begin
 if not TimeSpeedButton.Down then TimeSpeedButton.Caption := 'WinDir';
end;

procedure TClientForm.MemSpeedButtonClick(Sender: TObject);
begin
 if not MemSpeedButton.Down then MemSpeedButton.Caption := 'Cursor';
end;

procedure TClientForm.FormDestroy(Sender: TObject);
begin
 if Assigned(pSharedBuf) then UnMapViewOfFile(pSharedBuf);
 if hFileMapObj<>0 then CloseHandle(hFileMapObj);
end;

end.
Сервер:
Код:
unit srvUnit;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  ExtCtrls, StdCtrls, XPMan;

type
  TServerForm = class(TForm)
    Timer1: TTimer;
    XPManifest1: TXPManifest;
    Label1: TLabel;
    Label2: TLabel;
    Label3: TLabel;
    Label4: TLabel;
    procedure Timer1Timer(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

const MaxClients = 32;


var
  ServerForm: TServerForm;
  hFileMapObj: THandle;
  pSharedBuf:  Pointer;

implementation


{$R *.DFM}
type
 pDataRecord = ^TDataRecord;
 TDataRecord = record
  DateTime : PChar;
  Mem : Pchar;
  end;

procedure TServerForm.Timer1Timer(Sender: TObject);
 var
 buffer: array [0..255] of char;
 Win: PChar;

begin
  GetWindowsDirectory(buffer, SizeOf(buffer));
  win := buffer;
  Label2.Caption := win;

  pDataRecord(pSharedBuf)^.DateTime := win ;
  pDataRecord(pSharedBuf)^.Mem := win;
end;

procedure TServerForm.FormCreate(Sender: TObject);
begin
 hFileMapObj:=
   CreateFileMapping(MAXDWORD, nil, PAGE_READWRITE, 0, 50, '_SharedMem');
  if  (hFileMapObj=0) then
   begin ShowMessage('Cannot CreateFileMapping'); Application.Terminate; Exit; end;
  pSharedBuf :=
    MapViewOfFile(hFileMapObj, FILE_MAP_WRITE, 0, 0, 0);
  if (pSharedBuf = nil) then
   begin ShowMessage('Cannot MapViewOfFile'); Application.Terminate; end;
end;

procedure TServerForm.FormDestroy(Sender: TObject);
begin
 if Assigned(pSharedBuf) then UnMapViewOfFile(pSharedBuf);
 if hFileMapObj<>0 then CloseHandle(hFileMapObj);
end;

end.
iCaesy вне форума Ответить с цитированием
Старый 25.01.2012, 17:07   #2
_-Re@l-_
C++, Java
Старожил
 
Аватар для _-Re@l-_
 
Регистрация: 10.04.2010
Сообщений: 2,665
По умолчанию

Попробуйте AnsiString и PAnsiChar.
_-Re@l-_ вне форума Ответить с цитированием
Старый 25.01.2012, 19:03   #3
GunSmoker
Старожил
 
Регистрация: 13.08.2009
Сообщений: 2,581
По умолчанию

Ыыыыыы.... это крайне интересная логика копирования. Указывать чужой программе в своё адресное пространство, доступа к которому у чужой программы нет.

Читаем мат-часть:
Что такое память программы.
Как работают с PChar.

Если хотите кратко понять суть, то вот здесь - читать секцию "проецируемые файлы" и вот это (ключевые слова "это не скопирует текст 'Delphi' в массив A").
Опытный программист на C++ легко решает любые не существующие в Паскале проблемы.

Последний раз редактировалось GunSmoker; 25.01.2012 в 19:06.
GunSmoker вне форума Ответить с цитированием
Старый 25.01.2012, 20:05   #4
iCaesy
In progress...
Форумчанин
 
Регистрация: 25.09.2011
Сообщений: 161
По умолчанию

Не понял, почему чужой программе ? Если определить переменную типа integer, и передавать ее то все прекрасно работает, вся проблема именно в преобразовании чара в стринг...
iCaesy вне форума Ответить с цитированием
Старый 25.01.2012, 20:08   #5
GunSmoker
Старожил
 
Регистрация: 13.08.2009
Сообщений: 2,581
По умолчанию

Нет, друг, проблема не в преобразовании, а в непонимании фундаментальных основ.

Если тебе лень читать ссылки, можем сыграть в игру. Наводящий вопрос: сколько байт занимает TDataRecord?
Опытный программист на C++ легко решает любые не существующие в Паскале проблемы.
GunSmoker вне форума Ответить с цитированием
Старый 25.01.2012, 20:24   #6
iCaesy
In progress...
Форумчанин
 
Регистрация: 25.09.2011
Сообщений: 161
По умолчанию

Мне то не лень, этим я сейчас и занимаюсь. Играть в игру мне рановато, ибо дэлфи я изучаю 2й месяц, а это пример из выданной методички. И не пойму почему инт передает а со строками такие проблемы ?
iCaesy вне форума Ответить с цитированием
Старый 25.01.2012, 20:26   #7
GunSmoker
Старожил
 
Регистрация: 13.08.2009
Сообщений: 2,581
По умолчанию

Потому что число имеет фиксированный размер, а строки - переменный.
Опытный программист на C++ легко решает любые не существующие в Паскале проблемы.
GunSmoker вне форума Ответить с цитированием
Старый 25.01.2012, 20:28   #8
GunSmoker
Старожил
 
Регистрация: 13.08.2009
Сообщений: 2,581
По умолчанию

Это вообще для себя или для учёбы? Если второе, то я и лезть не буду, а если хочется разобраться, то могу подкидывать материал.
Опытный программист на C++ легко решает любые не существующие в Паскале проблемы.
GunSmoker вне форума Ответить с цитированием
Старый 25.01.2012, 20:31   #9
iCaesy
In progress...
Форумчанин
 
Регистрация: 25.09.2011
Сообщений: 161
По умолчанию

Спасибо за ссылки, попытаюсь разобраться .

Проблема в передачи неправильной длинны строки, я правильно понял ?

Последний раз редактировалось Stilet; 25.01.2012 в 21:42.
iCaesy вне форума Ответить с цитированием
Старый 25.01.2012, 21:20   #10
GunSmoker
Старожил
 
Регистрация: 13.08.2009
Сообщений: 2,581
По умолчанию

Нет. Проблема в том, что вы вообще строку не передаёте.

Строки - это динамические данные (не важно, PChar или String), потому что они могу иметь произвольный размер. Любые динамические данные суть указатель.

Указатель - это когда данные располагаются не в переменной. Переменная лишь указывает на данные.

Поэтому, TDataRecord имеет размер 2 * SizeOf(Pointer) - 8 байт. При всём желании в 8 байт строку уместить физически невозможно.

Поэтому, когда вы передаёте между программами TDataRecord - вы передаёте указатели, но не данные. Понятно, что указатели на данные программы в другой программе лишены смысла.

Ну, это как если бы я вставил в свою машину флешку, скинул бы на неё ярлыки (а не файлы) и перенёс на вашу машину - без исходных файлов (данных) ярлыки (указатели) бесполезны.

Вот откуда у вас мусор - указатели указывают на "что-то", но это "что-то" - в другой программе, не вашей. А в вашей по этим адресам лежит что-то совершенно другое - ваши данные.
Опытный программист на C++ легко решает любые не существующие в Паскале проблемы.
GunSmoker вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме 85 тыс рублей в месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
как перевести Pchar в string? green-shrek Помощь студентам 3 07.04.2010 19:01
гарантированный перевод string в PChar Пепел Феникса Общие вопросы Delphi 2 21.09.2009 11:44
String to PChar D7_beginner Общие вопросы Delphi 2 21.11.2007 14:05
проблема перевода (PChar и string) Fireleo Общие вопросы Delphi 4 29.07.2007 08:14
Как из string получить PChar??? sis Компоненты Delphi 4 11.02.2007 16:58