Вход | Регистрация
    1  2  3   

OFF: 1С - это годная вещь. Вы даже не знаете насколько.

OFF: 1С - это годная вещь. Вы даже не знаете насколько.
Я
   H A D G E H O G s
 
26.08.15 - 21:37
1. 1С: Божествена100% (1)
2. 1С: Предать анафиме0% (0)
Всего мнений: 1

Ночи доброй.

Давненько тем не заводил, некогда. Но напишу.

Часто слышу упреки в адрес 1С, как платформы, особенно в ветках по 8.3.6 :-)
Но, думаю, народ даже не подозревает, какой объем крови, пота и соплей Программистов фильтрует 1С-ка, защищая и оберегая их. Я и сам раньше не подозревал, но некоторые попытки написать некоторую систему на другом ЯП мне еще немного открыли глаза.

Берегите 1С, это ваши спокойные нервы :-)
 
 
   Забияка
 
1 - 26.08.15 - 21:40
(0)+100500..
   H A D G E H O G s
 
2 - 26.08.15 - 21:40
Ну и просто, задачка, съевшая мне мозг на один вечер (их на самом деле много было). Умеющим и имеющим Дельфи - велком.

procedure Test();
var
inData,outData:OleVariant;
DataSize:Integer;
RawData:Array of byte;
outDataAsString:string;
begin
inData:='Текстовая строка';
DataSize:=Length(inData)*2+2; //2 байта на символ + 2 байта на 2 "нулевых" символа в конце
Setlength(RawData,DataSize);
CopyMemory(@RawData[0],TVarData(inData).VOleStr,DataSize);

GetMem(TVarData(outData).VOleStr,DataSize);
CopyMemory(TVarData(outData).VOleStr,@RawData[0],DataSize);
TVarData(outData).VType:=varOleStr;
outDataAsString:=String(outData);
end;

Необходимо избавится от access violation и объяснить, что и почему пошло не так. Смысл задачи - "сериализация"/"десериализация" OleVariant.
   jsmith82
 
3 - 26.08.15 - 21:41
поддержу автора темы
   spectre1978
 
4 - 26.08.15 - 21:44
(0) в целом поддержу, но в ряде случаев дельфа все-таки рулит, например при дружбе с железками по всяким компортам/сокетам. Не, я понимаю, что в 1С это тоже можно. Но в гамаке и стоя.
   Забияка
 
5 - 26.08.15 - 21:45
(2)Дим, ты помощь ищешь в решении задачи? :)
   spectre1978
 
6 - 26.08.15 - 21:45
+ (4) короче, как обычно, нужно выбирать инструмент по задаче
   H A D G E H O G s
 
7 - 26.08.15 - 21:46
(5) Я уже решил.
   ДенисЧ
 
8 - 26.08.15 - 21:47
Шо, даже дельфя хуже? О_о
   spectre1978
 
9 - 26.08.15 - 21:50
(2) Когда-то что-то подобное я делал... кажется, выпихивал мелкий по размерам вариант в бинаридата ключ реестра. Только не уверен что найду.
   Enterprise
 
10 - 26.08.15 - 21:50
Изучал Делфи в колледже... что тут сказать, люблю 1С...
   wizard_forum
 
11 - 26.08.15 - 21:56
(8) Делфи не хуже! (как и прочее)
просто, в 1С многое сделали, чтобы ты не парился над мелочами
   tridog
 
12 - 26.08.15 - 21:56
(2) А этот ваш OleVariant в делфях это что такое? Тип-обертка для позднего связывания?
   jsmith82
 
13 - 26.08.15 - 21:59
дельфи я не люлю
мне си шарп по нраву. это красота
   mishaPH
 
Модератор
14 - 26.08.15 - 22:05
(0) У меня есть живей пример, уже 1.5 последних года. Система ERP на джаве и т.п. На которую мы переходим..
я с тобой полностью согласен.
   jsmith82
 
15 - 26.08.15 - 22:16
а куба чо, жива?
   Славен
 
16 - 26.08.15 - 22:17
После сапа, 1с божественна
   Asmody
 
17 - 26.08.15 - 22:25
Именно. 1С:Предприятие - пожалуй лучший фреймворк для быстрого создания бизнес-приложений. По продуктивности ближайшие аналоги где-то совсем неблизко. Работает это всё, местами, не очень, но во-первых, таких мест немного, а во-вторых, не бывает систем без багов.
   oleg_km
 
18 - 26.08.15 - 22:35
Параллельно пишу на шарпе - нет таких проблем. Вы еще с ассемблером сравните
   Злопчинский
 
19 - 26.08.15 - 22:38
1С - это мегапусечка...
   Zamestas
 
20 - 26.08.15 - 22:39
(2) Не пишите Вы на этой дряни - пользуйте (13,18).
   Пикчер
 
21 - 26.08.15 - 22:57
(2) паскакал не яп, а блевотина
   Wirtuozzz
 
22 - 26.08.15 - 23:00
1С нормальная штука, с учетом что аналогов то нет. Поэтому хорошо, что 1с  Предприятие есть и развивается.
   vde69
 
23 - 26.08.15 - 23:03
по сравнению с автолиспом 1с не просто божество а божество божества :)

вообще 1с очень хорошая среда разработки, у нее есть свои скелеты, но для бизнес логики это один из мировых лидеров в плане удобства и функционала.
   vde69
 
24 - 26.08.15 - 23:04
писал коммерческие проекты на кларионе, автолиспе, паскале.
был постановщиком для с++

1с - куда круче всего этого :)
   H A D G E H O G s
 
25 - 26.08.15 - 23:05
(12) Это всего лишь структура, с которой delphi прозрачно работает.
   H A D G E H O G s
 
26 - 26.08.15 - 23:06
Ну, граждане, кто осилит (2) ?
   H A D G E H O G s
 
27 - 26.08.15 - 23:06
(21) Сперва добейся.
   vde69
 
28 - 26.08.15 - 23:08
(26) на сколько я помню в дельфях есть 2 взаимоисключающих метода выделения и операций с памятью, мне кажется, что дело в этом...
   Zamestas
 
29 - 26.08.15 - 23:09
(26) +Где именно валится - не в CopyMemory(@RawData[0],TVarData(inData).VOleStr,DataSize);
случаем?
   H A D G E H O G s
 
30 - 26.08.15 - 23:10
(28) чего?
 
 Рекламное место пустует
   H A D G E H O G s
 
31 - 26.08.15 - 23:11
(29) Нет, валится на строке

outDataAsString:=String(outData);
   Пикчер
 
32 - 26.08.15 - 23:18
(31) ну ты памяти выделил на один тип, а просишь другой
   vde69
 
33 - 26.08.15 - 23:18
(30)я про работу с кучей, у тебя используется GetMem которая имеет ограничения

(31)по сколько валится на преобразовании типов, значит в outData содержится объект который не может быть преобразован в строку, нужно посмотреть значения массива
   viraboy
 
34 - 26.08.15 - 23:20
(0) Программистам которые на других языках не волокут и в 1С многого не светит. минимум скуль
   H A D G E H O G s
 
35 - 26.08.15 - 23:21
(32) И?
   H A D G E H O G s
 
36 - 26.08.15 - 23:23
(33) GetMem не имеет ограничений.
(33) "который не может быть преобразован в строку" - все можно "преобразовать" в строку.
   vde69
 
37 - 26.08.15 - 23:23
(35) например первый символ массива содержит число больше размера массива
   H A D G E H O G s
 
38 - 26.08.15 - 23:23
p.s. Запустите кто-нибудь Дельфи, это вас позабавит.
   H A D G E H O G s
 
39 - 26.08.15 - 23:23
(37) Ты застрял в 90-х.
   Zamestas
 
40 - 26.08.15 - 23:25
(38) Нету у меня дельфи - и ставить религия не позволяет.
Длина outData перед приведением к строке какая?
   Пикчер
 
41 - 26.08.15 - 23:26
(35) и на типизацию дай памяти. на точки кавычки. Что за хрень все байтами мерить не 90 е же
   H A D G E H O G s
 
42 - 26.08.15 - 23:26
(40) 16 байт.
   Пикчер
 
43 - 26.08.15 - 23:31
(42) я же говорю паскакал. где еще два
   Zamestas
 
44 - 26.08.15 - 23:35
(42) А если
DataSize:=Length(inData)*2+3;
Вылетает?
   H A D G E H O G s
 
45 - 26.08.15 - 23:36
(44) Вылетает. Но так делать нельзя.
   H A D G E H O G s
 
46 - 26.08.15 - 23:37
(43) В C++ проблема будет точно такая -же. Скорее всего.
   Zamestas
 
47 - 26.08.15 - 23:37
(45) Мля да там DataSize везде пляшет.
   Zamestas
 
48 - 26.08.15 - 23:39
(47) Скорее Setlength(RawData,DataSize+1);
   Лефмихалыч
 
49 - 26.08.15 - 23:39
(0) ты прямо Христофор Доминикович Колумб...
   H A D G E H O G s
 
50 - 26.08.15 - 23:39
(48) Гадание не поможет. Только отладчик.
   Американец1
 
51 - 26.08.15 - 23:44
При конвертации string в массив байтов ты потерял длину строки, которая хранится по отрицательному смещению.
   Zamestas
 
52 - 26.08.15 - 23:44
(50) Ну дяди OleVariant в String на дельфях как то так пихают:
http://www.foxbase.ru/delphi/vzaimnye-preobrazovaniya-olevariant-i-string.htm
   H A D G E H O G s
 
53 - 26.08.15 - 23:46
(51) Ура. Опыт?
   Американец1
 
54 - 26.08.15 - 23:46
(53) Огромный
   H A D G E H O G s
 
55 - 26.08.15 - 23:48
Собственно, пример я привел к тому, что BSTR строки хранят свою длину в 4 байтах до указателя, и слава яйцам, что 1С ограждает нас от таких знаний.

Самое забавное, что Дельфи в отладчике ориентируется на C++ строку и нормально ее показывает.
   Американец1
 
56 - 27.08.15 - 00:06
Так сработает:
//  CopyMemory(TVarData(outData).VOleStr,@RawData[0],DataSize);
TVarData(outData).VOleStr := PChar(WideString(PChar(@RawData[0])));


Там еще забавные грабли есть.
BSTR хранит длину в байтах, а string в символах.
Можно нарваться если кастить бездумно.

Например так не сработает. Обрежет строку наполовину
TVarData(outData).VOleStr := PChar(string(PChar(@RawData[0])));
   H A D G E H O G s
 
57 - 27.08.15 - 00:10
(56) Передай OleVariant по сети, говорили они. Это удобно, в нем все есть, говорили они...
   Американец1
 
58 - 27.08.15 - 00:10
//GetMem(TVarData(outData).VOleStr,DataSize);
Это лишнее. Тем более, что никто потом не освобождает.
   H A D G E H O G s
 
59 - 27.08.15 - 00:12
Я сделал так:

      if TVarData(currentElement^.Data).VType = varOleStr then
      begin // В переменной - строка, ее храним отдельно
        datasize := sizeof(Integer); // Длина строки
        CopyMemory(@DataLength, position, datasize);
        position := ptr(THandle(position) + datasize);
        datasize := DataLength * 2;
        GetMem(DataPointer, datasize + 6);
        CopyMemory(DataPointer, @datasize, 4); // Длина строки для WideString
        DataPointer := ptr(THandle(DataPointer) + 4);
        datasize := datasize + 2;
        CopyMemory(DataPointer, position, datasize); // Длина строки для WideString
        TVarData(currentElement^.Data).VOleStr := DataPointer;
        position := ptr(THandle(position) + datasize);
      end;
   H A D G E H O G s
 
60 - 27.08.15 - 00:13
(58) Это мне поток eureka скажет, пока не до этого.
   H A D G E H O G s
 
61 - 27.08.15 - 00:13
поток -> потом
   Американец1
 
62 - 27.08.15 - 00:13
У тебя утечка памяти.
   Американец1
 
63 - 27.08.15 - 00:14
Мой способ короче :)
   H A D G E H O G s
 
64 - 27.08.15 - 00:15
(62) Дельфи, когда будет убивать переменную currentElement^.Data - должна ее почистить.
   Американец1
 
65 - 27.08.15 - 00:17
(64)
Не почистит. Компилятор не знает как и чем ты выделял память.

Если явно вызывал GetMem должен явно и освобждать.
   H A D G E H O G s
 
66 - 27.08.15 - 00:18
Нигде, кстати, не нашел, что WideString работает со строкой, как с BSTR строкой.

Вот, кстати,
http://www.delphibasics.ru/WideString.php

путают WideString (BSTR) и AnsiString (String от Delphi)
 
 Рекламное место пустует
   H A D G E H O G s
 
67 - 27.08.15 - 00:18
(65) Счаст проверим.
   H A D G E H O G s
 
68 - 27.08.15 - 00:19
(67) Че ему знать, он видит OleVariant в которой есть указатель на BSTR строку. Должен ее почистить.
   Американец1
 
69 - 27.08.15 - 00:21
(66) По факту это так. Для WideString память выделяется с виндовой кучи SysAllocStringLen.

(68) Если попытается - слетит.
Для BSTR вызывается SysFreeString. А ты выделил через GetMem. Это разные кучи (heap)
   Американец1
 
70 - 27.08.15 - 00:22
procedure Test();
var
  inData,outData:OleVariant;
  DataSize:Integer;
  RawData:Array of byte;
  outDataAsString:string;
  outDataAsStringW:WideString;
begin
  inData:= 'Текстовая строка';
  DataSize:=Length(inData)*2+2; //2 байта на символ + 2 байта на 2 "нулевых" символа в конце
  Setlength(RawData,DataSize);
  CopyMemory(@RawData[0],TVarData(inData).VOleStr,DataSize);
  TVarData(outData).VType:=varOleStr;
  TVarData(outData).VOleStr := PChar(WideString(@RawData[0]));
  outDataAsString:=String(OutData);
  outDataAsString:=String(TVarData(outData).VOleStr);
end;
   H A D G E H O G s
 
71 - 27.08.15 - 00:23
(69) Понятно.
   H A D G E H O G s
 
72 - 27.08.15 - 00:23
(69) У BSTR есть 2 нулевых байта в конце?
   Американец1
 
73 - 27.08.15 - 00:25
(72) Да есть
   H A D G E H O G s
 
74 - 27.08.15 - 00:26
Да, утекло 38 байт.

procedure Test();
var
inData,outData:OleVariant;
DataSize:Integer;
RawData:Array of byte;
outDataAsString:string;
DataPointer:Pointer;
begin
inData:='Текстовая строка';
DataSize:=Length(inData)*2+2; //2 байта на символ + 2 байта на 2 "нулевых" символа в конце
Setlength(RawData,DataSize);
CopyMemory(@RawData[0],TVarData(inData).VOleStr,DataSize);

GetMem(DataPointer,DataSize+4);
CopyMemory(DataPointer,@DataSize,4);
DataPointer:=ptr(THandle(DataPointer)+4);

CopyMemory(DataPointer,@RawData[0],DataSize);
TVarData(outData).VType:=varOleStr;
TVarData(outData).VOleStr:=DataPointer;
outDataAsString:=String(outData);
end;
   H A D G E H O G s
 
75 - 27.08.15 - 00:27
Ладно, спасибо большое про "Для WideString память выделяется с виндовой кучи SysAllocStringLen"

Чувствую, сношался бы с этим.
   H A D G E H O G s
 
76 - 27.08.15 - 00:27
(75) И вот хрен где это найдешь.
   Американец1
 
77 - 27.08.15 - 00:29
Кстати, не два нулевых байта, а два нулевых симбола (4 байта)
Это позволяет иметь нулевые символы в середине BSTR строки
   Американец1
 
78 - 27.08.15 - 00:29
(75) Было приятно вспомнить.
   H A D G E H O G s
 
79 - 27.08.15 - 00:34
(77) Точно?
   H A D G E H O G s
 
80 - 27.08.15 - 00:42
   Американец1
 
81 - 27.08.15 - 00:43
(79) Точно
A string of Unicode characters. May contain multiple embedded null characters.
https://msdn.microsoft.com/en-us/library/windows/desktop/ms221069(v=vs.85).aspx

Но если миксить с Delphi string то строка обрежется до первого ноля.
   Американец1
 
82 - 27.08.15 - 00:47
(80) null terminator опциональный для BSTR. Его может и не быть.

В твоем случае это не null terminator, а нулевой символ.

Сделай String(@RawData[0]) и увидишь
   H A D G E H O G s
 
83 - 27.08.15 - 00:57
(82) неа.

Сделай String(@RawData[0]) и увидишь

Я вижу это не потому что там нулевой символ, а потому что Дельфи привело это к типовой структуре String.

type
PStrRec = ^StrRec;
StrRec = packed record // Заголовок строки 8 байт
  refCnt: Longint; // 4 байта – счетчик ссылок
  length: Longint; // 4 байта – длина строки
end;

Но String считает длину строки в символах, а BSTR в байтам, в получается, что Дельфи получило строку в 2 раза больше (префикс BSTR попал в поле length) и выползло за пределы строки.
   Американец1
 
84 - 27.08.15 - 00:59
Ok. А теперь посмотри

WideString(@RawData[0]);
   H A D G E H O G s
 
85 - 27.08.15 - 01:04
(84) гхм..

"Не могу узреть под таким углом"
   H A D G E H O G s
 
86 - 27.08.15 - 01:09
Все, я окончательно затупил.
В 4 байтах перед @RawData[0] вообще содержится мусор, и на него не ориентируется WideString(@RawData[0]), раз показывает "приемлимую" строку, так?
   Американец1
 
87 - 27.08.15 - 01:10
А так :)
WideString(PChar(@RawData[0]));

В этом случае байты сначала кастятся в С-style sting (PChar)
До первого нуля.

Потом С string кастится в string(WideString) которая хранит длину без учета терминатора
   H A D G E H O G s
 
88 - 27.08.15 - 01:11
Значит WideString(@RawData[0]) идет до нулевых символов, так?
Она останавливается, когда встречает 2 нулевых байта, и предыдущий нулевой включает в значущую строку?
   H A D G E H O G s
 
89 - 27.08.15 - 01:17
Ладно, сколько там у вас по Североамериканско-Восточному? 18:17? Пора домой. А мне - спать.
   Американец1
 
90 - 27.08.15 - 01:29
(88) Да, именно так. Вызывается С-style Length, которая идет до первого ноля.
Спок ночи.
   Снежный человек
 
91 - 27.08.15 - 02:11
Надо 1СИконы.Делать и по Улица.Ходить, благодарить Братьев за пищу.
   Трик
 
92 - 27.08.15 - 07:25
Надо на мисте уже под форум делать по другим языкам :).
   ifso
 
93 - 27.08.15 - 07:28
(92) или лучше падаждем гуглопромтовского автоперводчика, не?)
   Трик
 
94 - 27.08.15 - 08:15
@ H A D G E H O G s

а зачем тебе дельфи? И на чем еще пишешь помимо? :)
   rphosts
 
95 - 27.08.15 - 08:16
(0) +100500, мне очень нравилось что Нуралиев финансирует в т.ч. развитие всяких механизмов потребность в которых не особо и велика но иногда они реашют!
   spectre1978
 
96 - 27.08.15 - 08:17
(94) ну попробуй напиши на 1С, скажем, открытие бинарника (EXE, DLL) и показ его на форме в 16-ричном виде
   spectre1978
 
97 - 27.08.15 - 08:18
+ (96) или софт сбора данных с сотни датчиков, среди которых есть подключенные по Ethernet, по RS422 и RS485
   Трик
 
98 - 27.08.15 - 08:20
(97) две большие разницы подрабатывает ли 1сник еще просто прогом в органзации или совокупляет 1с с чем то:).
   spectre1978
 
99 - 27.08.15 - 08:25
(98) я не вижу разницы. Есть задачи по автоматизации, можешь - решаешь, получаешь бабло. Мне все равно. Я вполне могу сегодня с PLC в цеху махаться, а завтра бухам расчеты в ЗУП смотреть.
   spectre1978
 
100 - 27.08.15 - 08:28
и дельфа очень даже годный инструмент. А ребятам - ежу и американцу - респект. Сейчас прочитал - прямо студенческие годы вспомнил... Так же и я когда-то ковырялся в системном программировании, сейчас, правда, это надо все реже и реже
  1  2  3   

Список тем форума
Рекламное место пустует  Рекламное место пустует
ВНИМАНИЕ! Если вы потеряли окно ввода сообщения, нажмите Ctrl-F5 или Ctrl-R или кнопку "Обновить" в браузере.
Тема не обновлялась длительное время, и была помечена как архивная. Добавление сообщений невозможно.
Но вы можете создать новую ветку и вам обязательно ответят!
Каждый час на Волшебном форуме бывает более 2000 человек.