Форум: "Основная";
Текущий архив: 2002.03.11;
Скачать: [xml.tar.bz2];
ВнизПомогите преобращовать Record в Variant! Найти похожие ветки
← →
Last Hero (2002-02-19 21:38) [0]Проблема. Нужно преобразовать переменную типа Record в Variant. Существует очень много статей, как это сделать с массивами, картинками, бинарной информацией, но нигде не нашел, как преобразовать Record.
Помогите!!!!!!!!
← →
Last Hero (2002-02-20 08:26) [1]Ответьте!!! Please...
Как можно преобразовать Record в Variant Array? И можно ли? А также обратно преобразовать в Record... И, пожалуйста, просто пример кода!!!
← →
Digitman (2002-02-20 08:51) [2]никак. переменные вариантного типа не поддерживают автоматическое управление распределением памяти под пользовательские типы данных
← →
SEM (2002-02-20 10:39) [3]Может я не понял вопроса, но может быть спасет
функция VarArrayCreate, с помощью которой можно создать
массив байтов примерно так:
V: Variant;
...
V := VarArrayCreate([...], varByte);
И копирнуть туда record.
← →
Юрий Федоров (2002-02-20 11:04) [4]И для копирования использовать VarArrayLock, VarArrayUnLock
← →
Last Hero (2002-02-20 13:57) [5]>SEM © and Юрий Федоров ©
Именно это я и имел в виду, пожалуйста, приведите пример, как это можно сделать?
← →
Набережных С. (2002-02-20 16:21) [6]Посмотри
http://www.delphikingdom.com/asp/answer.asp?IDAnswer=9090
← →
Last Hero (2002-02-20 20:24) [7]Сделал все так, как в примере...
Я таким образом пытаюсь передать данные на сервер приложений (MIDAS)...
Все нормально компилится, как будто работает (то есть в данных в примере строчках кода никаких exception нет), но при попытке обращения на сервере к любому из полей рекорда появляется Access Violation :-(
Как это может быть?
← →
Набережных С. (2002-02-20 21:32) [8]Покажи код
← →
Last Hero (2002-02-20 23:00) [9]Запись (в TLB, экспортирую и в сервер и в клиент):
StudentRecord = packed record
ID: Integer;
Main: MainStudentRecord;
Address: AddressRecord;
Passport: PassportRecord;
Reference: ReferenceRecord;
MainSchool: SchoolRecord;
MainCollege: CollegeRecord;
MainGraduate: GraduateRecord;
MainMaster: MasterRecord;
MainAdditional: AdditionalRecord;
MainDriver: DriverRecord;
language1: LanguageRecord;
language2: LanguageRecord;
language3: LanguageRecord;
language4: LanguageRecord;
language5: LanguageRecord;
Work1: WorkRecord;
Work2: WorkRecord;
Work3: WorkRecord;
Work4: WorkRecord;
Work5: WorkRecord;
knollege: WideString;
notes: WideString;
end;
MainStudentRecord = packed record
Photo: OleVariant;
FirstName: WideString;
SecondName: WideString;
LastName: WideString;
Birthday: TDateTime;
Sex: Integer;
FamilyStatus: Integer;
Military: Integer;
end;
// Далее различные рекорды, на которые ссылается StudentRecord
Клиент:
var StudData : StudentRecord;
StudOle : OleVariant;
PStudData : Pointer;
//..........................................................
// Здесь заполняется StudData значениями, которые я хочу послать на сервер
//..........................................................
StudOle := VarArrayCreate([0, SizeOf(StudentRecord)], varByte);
PStudData := VarArrayLock(StudOle);
try
Move(StudData, PStudData^, SizeOf(StudentRecord));
finally
VarArrayUnlock(StudOle);
end;
// Вызываю серверную процедуру, передавая ей запись StudOle
ID := DataModule1.SocketConnection1.AppServer.Add_Student(StudOle, ErrMsg);
Сервер:
function TCcs_serv_rdm.Add_student(OleStudData: OleVariant;
out ErrMsg: WideString): Integer;
var POleStudData : pointer;
StudData : StudentRecord;
// ............................................................
begin
// Раскрываем OleStudData в StudData
POleStudData:=VarArrayLock(OleStudData);
Move(POleStudData^, StudData, SizeOf(StudData));
VarArrayUnLock(OleStudData);
try
ShowMessage(StudData.Main.FirstName); // Просто хочу вывести что-нибудь, и здесь возникает Access Violation. То же самое происходит и при любом другом подобном вызове
except
on E : Exception do ShowMessage(E.Message)
end;
← →
Last Hero (2002-02-20 23:04) [10]Sorry, это я просто уже экспериментировал... Поправка, чтобы выглядело как в примере:
Сервер:
function TCcs_serv_rdm.Add_student(OleStudData: OleVariant;
out ErrMsg: WideString): Integer;
var POleStudData : pointer;
StudData : StudentRecord;
// ............................................................
begin
// Раскрываем OleStudData в StudData
POleStudData:=VarArrayLock(OleStudData);
Move(POleStudData^, StudData, SizeOf(StudentRecord));
VarArrayUnLock(OleStudData);
try
ShowMessage(StudData.Main.FirstName); // Просто хочу вывести что-нибудь, и здесь возникает Access Violation. То же самое происходит и при любом другом подобном вызове
except
on E : Exception do ShowMessage(E.Message)
end;
← →
Digitman (2002-02-21 09:04) [11]а как ты думаешь, чему равно значение SizeOf(StudData.Main.FirstName) ?
← →
Digitman (2002-02-21 09:26) [12]1. Посчитай, сколько всего полей в записи StudentRecord (включая поля во всех вложенных в нее записях - MainStudentRecord, LanguageRecord и т.д.). Пусть полученное тобой значение будет равно N.
2. Создай на кл.стороне массив
var
StudOle : OleVariant;
StudOle := VarArrayCreate([0, N - 1], OleVariant);
3. Заполни массив
var
StudData : StudentRecord;
with StudData do begin
StudOle[0]:= ID;
...
StudOle[1]:= Main.FirstName;
...
StudOle[N-1]:= notes;
StudOle[N-2]:= knollege;
end;
4. Передай StudOle серверу в параметре вызова Add_student(), так, как ты это и делал ранее
5. На серв.стороне создай экз-р записи
var
StudData : StudentRecord;
6. Заполни экз-р из принятого параметром массива
with StudData do begin
OleStudData[0]:= ID;
...
OleStudData[1]:= Main.FirstName;
...
OleStudData[N-1]:= notes;
OleStudData[N-2]:= knollege;
end;
Это - самый надежный и верный способ в ситуации, когда структуры данных изначально не продуманы в части потенциальной необходимости трансляции их в иное АП с использованием OLE-механизма !
← →
Last Hero (2002-02-21 12:16) [13]> Digitman ©
Спасибо
Придется видимо так, жаль, не очень все таки изящное решение, вот захочется мне в какую нибудь запись новое поле добавить, и все индексы придется менять, или логическое их следование будет крайне неудачным :-(
← →
Digitman (2002-02-21 12:59) [14]чтобы твое "изящное" решение с минимальными затратами/переделками адаптировать к OLE-механизму, посоветую следующее :
- откажись от WideString - этот тип в данном контексте совершенно необязателен; используй вместо него string[k], где k -максимально возможное число символов, предполагаемое в любой из строк, формирующих значения текст.полей любой из задействованных тобой структур;
- обрати особое внимание на поле MainStudentRecord.Photo -
при передаче на сервер этого поля ты можешь снова "наступить на те же грабли", если поле инициализировано как вариантная переменная, содержащая не собственно данные, а ссылку на них в АП клиента
← →
Набережных С. (2002-02-21 16:15) [15]Digitman © (21.02.02 12:59) практически все сказал, добавить остается немногое.
> вот захочется мне в какую нибудь запись новое поле добавить,
> и все индексы придется менять, или логическое их следование
> будет крайне неудачным
Эта проблема давно решена путем передачи метаданных.
Реализация маршалинга через вариантный массив конечно проще, чем полноценная реализация IMarshal и уступает, пожалуй, только в скорости, но не стоит за это браться, не разобравшись досконально в особенностях всех типов данных.
← →
SerVS - S (2002-02-21 17:58) [16]var s: string;
v: variant;
begin
...
SetLength(s, Sizeof(TYourRecord));
Move(YourRecord, s, SizeOf(TYourRecord));
v := s;
...
end;
Обратно точно также! Извини не уверен за порядок параметров в Move
← →
Digitman (2002-02-21 18:44) [17]>SerVS - S
Ты о чем ?
Мы вот тут - о маршаллинге как бы)
← →
SerVS - S (2002-02-22 18:52) [18]Я заметил ;), но вопрос был как преобразовать рекорд с вариант.
Если длина полей в Рекорде постоянная, то результат получите такой как просили. Если внутри есть строки, дин.массивы и т.д. то постепенно, в вопросе было "Существует очень много статей, как это сделать с массивами, картинками, бинарной информацией". Ну вот и воспользуйся этим всем последовательно ;) (одна функция для упаковки вторая для распаковки)
← →
Набережных С. (2002-02-22 19:45) [19]
> SerVS - S (21.02.02 17:58)
Вариант рабочий(если устранить ошибку), но неоптимальный по скорости.
Страницы: 1 вся ветка
Форум: "Основная";
Текущий архив: 2002.03.11;
Скачать: [xml.tar.bz2];
Память: 0.49 MB
Время: 0.003 c