Вверх ↑
Этот топик читают: Гость
Разработчик
Ответов: 26153
Рейтинг: 2127
#31: 2008-03-11 14:04:12 ЛС | профиль | цитата
Galkov писал(а):
есть разница
Да там она, куда не ткнись, есть.
карма: 22

0
Ответов: 2125
Рейтинг: 159
#32: 2008-03-11 15:50:12 ЛС | профиль | цитата
Galkov писал(а):
tsdima, признавайся
KOLEdb.StringToOleStr - твоя работа ?

Никогда не трогал KOLEdb.
Когда я дорабатывал VBJScript, я вносил какие-то изменения в KOLComObj. Судя по подчерку, я изменил OleStrToStrVar, т.к. системная функция WideCharToStrVar (которая там была использована, наверное) в FPC глючная. А вот рядышком есть StringToOleStr, я её переделывать не стал. Она, кстати, использует системную функуцию FPC StringToWideChar, которая, возможно, работает нормально.
------------ Дoбавленo:

tsdima писал(а):
которая, возможно, работает нормально

Нифига, блин, не работает.
А если вот так, то работает:

#pas
function StringToLPOLESTR(const Source: string): POleStr;
var
SourceLen: Integer; Buffer: array of WideChar;
begin
SourceLen := Length(Source);
SetLength(Buffer, SourceLen+1);
//StringToWideChar(Source, Buffer, SourceLen); Buffer[SourceLen] := #0;
MultiByteToWideChar(0,0,@Source[1],SourceLen,Buffer,(SourceLen+1)*2);
Result := SysAllocString(Buffer);
end;

И ещё бага, вот исправленный вариант:

#pas
procedure THIVBJScript.SetScript;
var
Result: OleVariant;
ExcepInfo: TEXCEPINFO;
begin
CreateScriptEngine(TScriptLanguage(_prop_Language));
Me := TMe.Create(Self);
AddNamedItem('sys', SCRIPTITEM_ISVISIBLE, Me);
FParser.ParseScriptText(StringToOleStr(Value), nil, nil, nil, 0, 0, 0, Result, ExcepInfo);
end;
карма: 1

0
Ответов: 9906
Рейтинг: 351
#33: 2008-03-11 15:51:55 ЛС | профиль | цитата
Значит - плохой моя экстрасенс

Вообще-то, коды конечно - смерть всем китайцам....
StringToOleStr - конструктор, устойчивость - нулевая
Как таким можно пользоваться - уму непостижимо


Ну ладно, или будем что-то делать, или будем что-то решать...

карма: 9

0
Ответов: 2125
Рейтинг: 159
#34: 2008-03-11 16:00:44 ЛС | профиль | цитата
Есть, правда, подозрение, что в SetScript утечка памяти будет. То что вернул StringToOleStr удалять надо.
карма: 1

0
Ответов: 9906
Рейтинг: 351
#35: 2008-03-11 16:14:03 ЛС | профиль | цитата
tsdima писал(а):
То что вернул StringToOleStr удалять надо

В KOLComObj - удаляют, насколько я увидел

Вот в чем проблема: у меня нет объема тестирования (фикс для KOLEdb на SVN), потому-что во всяких там ODBC, я - дуб-дерево
Пример из этого топика, вроде работает...
Грубо говоря, просто тупо взял код из ImageLoader-а, хотя и возникает вопрос: не перенести ли фиговинку типа StringToWideString - в share
карма: 9

0
Разработчик
Ответов: 26153
Рейтинг: 2127
#36: 2008-03-11 16:17:20 ЛС | профиль | цитата
Galkov писал(а):
не перенести ли фиговинку типа StringToWideString - в share
А может это -- лучший вариант, что бы не копировать из угла в угол
карма: 22

0
Ответов: 9906
Рейтинг: 351
#37: 2008-03-11 16:22:12 ЛС | профиль | цитата
Да, вот еще, tsdima: константа KOLComObj. _P_ - это уж точно твоя...
Так вот, тройка - адекватнее...
Это я не придумал, это я подсмотрел в дельфячих сырцах
Там посложнее правда: для младших виндов идут особо тонкие разборки в initialization для определения кодовой страницы именно текущего потока
карма: 9

0
Ответов: 2125
Рейтинг: 159
#38: 2008-03-11 17:12:51 ЛС | профиль | цитата
Galkov писал(а):
константа KOLComObj. _P_ - это уж точно твоя...

Сочетания букв "_P_" в текстовых файлах в каталоге HiAsm я у себя не нашёл. Вывод - не моя.
И потом, переменным я даю нормальные, человеческие имена
карма: 1

0
Ответов: 9906
Рейтинг: 351
#39: 2008-03-11 23:30:42 ЛС | профиль | цитата
tsdima писал(а):
Вывод - не моя

Ну ты даешь
Это кто писал
tsdima писал(а):
Судя по подчерку, я изменил OleStrToStrVar

Смотрим и видим:

#pas
procedure OleStrToStrVar(const strFrom:POleStr; var strTo:string);
var DestLen:integer;
begin
DestLen := WideCharToMultiByte(_P_, 0, strFrom, -1, nil, 0, nil, nil);
if DestLen=1 then strTo:=' else begin
SetLength(strTo, DestLen-1);
WideCharToMultiByte(_P_, 0, strFrom, -1, @strTo[1], DestLen-1, nil, nil);
end;
end;

И мое утверждение состоит в том, что должно быть _P_=3, а не нулю
А что после этого про FPC говорить...
Они - никсоиды, и имеют право не понимать особо тонкой разницы между CP_THREAD_ACP и CP_ACP, наверное

------------ Дoбавленo:

tsdima писал(а):
И ещё бага, вот исправленный вариант:

А чего не фиксишь
И, кстати говоря еще раз, кто будет класть "гранату" на место
Уж коль скоро в фиксе ты собираешься использовать StringToOleStr, который является конструктором...
Ноги за такие конструкторы отрывать надо, в т.ч. и авторам системного варианта этого безобразия
карма: 9

0
Ответов: 2125
Рейтинг: 159
#40: 2008-03-12 11:06:36 ЛС | профиль | цитата
Galkov писал(а):
Смотрим и видим

Может _Р_ и должно быть 3, но у меня никакой константы нет, а тупо стоит ноль.
А что, на SVN я что-ли с такими буквами коммитил? Если и так, то видимо сильно пьян был

Galkov писал(а):
StringToOleStr, который является конструктором

При чём тут конструктор? Или ты имеешь ввиду, что память выделяется?
А как тогда иначе вернуть строку? Массив WideChar по ссылке передавать?
Насколько я понимаю, массив WideChar и OleStr - не одно и то же.

карма: 1

0
Ответов: 9906
Рейтинг: 351
#41: 2008-03-12 12:06:46 ЛС | профиль | цитата
tsdima писал(а):
А что, на SVN я что-ли с такими буквами коммитил?
Кстати, я тоже не помню происхождения файла...
Это выдержки из compilerFpcKOLComObj.pas, которого нет на SVN, а когда я прокачивал последний раз Compiler_fpc.exe - уже тоже и не вспомню...

tsdima писал(а):
При чём тут конструктор? Или ты имеешь ввиду, что память выделяется?
Имею, и очень настырно.
Причем, когда конструктор (StringToOleStr) находится у нутре компилятора, а деструктор (SysFreeString) находится у нутре оси - это уже беспредел в квадрате
Грешить, ИМХО, логичнее на этот беспредел, а не на глючность FPC
((Ну может еще на то, что никсоиды, в отличие от дяденьки Бормана, тоже тупо нулик всегда предпочитают лепить))

tsdima писал(а):
А как тогда иначе вернуть строку? Массив WideChar по ссылке передавать?
Насколько я понимаю, массив WideChar и OleStr - не одно и то же
Слушай, ну ты посмотри то, чего в ImageLoader (и что сейчас я воткнул в KOLEdb)
И скажи свое мнение.
Вопрос-то действительно серьезный, и я действительно не умею тестировать KOLEdb

Философский аспект этой проблемы я понимаю так (в cpp-шном изложении)
Существует два подхода:
  • создать объект какого-то класса через new, и вернуть указатель на этот объект
  • не создавать объект, а иметь типом результата ссылку на этот объект
    Первый случай, это то, что мы видим, и упираемся в тупики типа "А как тогда иначе вернуть строку?", когда даже уничтожать нечего (имени-то нет у результата), а по логике - надо бы.
    Во втором случае, объект создается вызывающей ф-ей (невидимая локальная переменная) и его адрес передается как дополнительный аргумент.
    При выходе из зоны видимости этой невидимой локальной переменной - она уничтожается (с вызовом деструктора) автоматически.
    Это в cpp - так, он это обязан делать (насколько я понимаю) с любым типом.
    А в дельфях этот второй фокус делается только со своими, особо любимыми типами
    К которым относится String, wideString...
    Тут уж я не виноват...
    ------------ Дoбавленo:

    tsdima писал(а):
    Может _Р_ и должно быть 3, но у меня никакой константы нет, а тупо стоит ноль.

    На это я тебе вот чего скажу:
    В ImageLoader кодовая страничка выделена как отдельный аргумент для StringToWideString, и вызывается с тройкой
    Так вот, если подставить нулики, то, не раз упомянутый Ведмедь.jpg - не читается
    А с тройкой - легко
  • карма: 9

    0
    Разработчик
    Ответов: 26153
    Рейтинг: 2127
    #42: 2008-03-12 12:35:53 ЛС | профиль | цитата
    Galkov писал(а):
    Это в cpp - так, он это обязан делать (насколько я понимаю) с любым типом.
    А в дельфях этот второй фокус делается только со своими, особо любимыми типами
    К которым относится String, wideString...
    Тут хочется немного добавить, на будущее, что очищать ресурс приходится и в API-функциях, работающих с GDI-ресурсами, где последние созданы конструктором внутри функции, ну не хотят эти функции делать автофри, хоть ты лопни.
    карма: 22

    0
    Ответов: 2125
    Рейтинг: 159
    #43: 2008-03-12 12:50:22 ЛС | профиль | цитата
    Galkov писал(а):
    конструктор (StringToOleStr) находится у нутре компилятора, а деструктор (SysFreeString) находится у нутре оси

    "у нутре компилятора" FPC есть только:
    StringToWideChar
    WideCharToString
    WideCharToStrVar
    WideCharLenToString
    WideCharLenToStrVar
    А StringToOleStr это уже КОЛовское, и конструктор там - SysAllocString, т.е. тоже "у нутре оси".
    А WideString тоже объект, как и string.

    Galkov писал(а):
    А в дельфях этот второй фокус делается только со своими, особо любимыми типами

    Делается с любыми объектами. Не делается с указателями.
    Как человек, пишущий в основном на C, я вообще до сих пор не въеду в принципы Дельфячих объектов/указателей_на_объекты.
    Особо раздражает, что это вроде как одно и то же. Там что, у объектов всегда счётчик ссылок есть?

    ------------ Дoбавленo:

    Galkov писал(а):
    Слушай, ну ты посмотри то, чего в ImageLoader

    Ну, с учётом того, что там возвращается объект, а не указатель на данные, вроде бы всё чисто.
    Объект, даже временный, всё равно рано или поздно уничтожится.

    карма: 1

    0
    Ответов: 9906
    Рейтинг: 351
    #44: 2008-03-12 13:26:00 ЛС | профиль | цитата
    tsdima писал(а):
    А StringToOleStr это уже КОЛовское, и конструктор там - SysAllocString, т.е. тоже "у нутре оси"

    А разве только о FPC речь
    Вот нарезка из Delpi7\Source\Rtl\Sys\System.pas
    
    #pas
    function StringToOleStr(const Source: string): PWideChar;
    begin
    Result := nil;
    _WStrFromPCharLen(WideString(Pointer(Result)), PChar(Pointer(Source)), Length(Source));
    end;
    Кстати, как эта фигня вообще работает (а в варианте Дельфи работает именно она) - не пойму...
    Какие-то не декларированные особенности языка: результат работы конструктора WideString - не уничтожается по выходе из зоны видимости
    Полный атас...

    tsdima писал(а):
    Делается с любыми объектами. Не делается с указателями

    Это как бы зависит от того, что называть словом "делается"
    Для тебя, как человека, пишущего в основном на C, этого должно означать вызов деструктора
    В этом аспекте - дулю с маком
    Типовой случай из наших кодов
    
    #pas
    dt := _doData('test');
    Да, создастся невидимая локальная переменная (которая потом радостно перекопируется в dt - тоже дурдом ведь), и ее адрес пойдет вторым аргументом в ф-ю _doData
    Да, сей объект будет уничтожен по выходе из зоны видимости.
    А вот как правильно уничтожать - тебя никто спрашивать не будет, хоть целое сочинение напиши в деструкторе, не будет он вызываться
    А ручками вызвать Destroy ты тоже не можешь - имени-то у этой невидимой локальной переменной и нету

    tsdima писал(а):
    я вообще до сих пор не въеду в принципы Дельфячих объектов/указателей_на_объекты

    Аналогично
    Только результаты каких-то изнурительных экспериментов за плечами...
    И фиг его знает, где про это можно прочитать
    Инет завален литературой для пользователей, которым "а больше мне нафиг и не надо"...
    А то, что именуется литературой "для профессионалов", больше напоминает расширенное справочное пособие.
    Типа, профессиналам тоже понимание не обязательно, им достаточно просто инфы про либы напихать по самое нихочу - и пусть подавятся
    карма: 9

    0
    Ответов: 2125
    Рейтинг: 159
    #45: 2008-03-12 14:37:58 ЛС | профиль | цитата
    Galkov писал(а):
    результат работы конструктора WideString - не уничтожается

    А тут нету никакого вызова конструктора Pointer конвертируется в WideString (конвертирование объект <-> pointer происходит без дополнительных действий), и он же передаётся как аргумент, по ссылке.
    WideString(Pointer(Result)) или WideString(Result), в данном случае скорее всего не безразлично

    карма: 1

    0
    Сообщение
    ...
    Прикрепленные файлы
    (файлы не залиты)