|
Вопрос # 3 621/ вопрос открыт / |
|
Здравствуйте, уважаемые эксперты!
Моя проблема заключается вот в чём:
Есть dll с унифицированной функцией function ObeyCommands(Arg: string): pointer;
В ней, в зависимости от того какой Arg выполняются разные действия и она выдаёт поинтеры на разные значения (типы данных у значений тоже разные)
В ней код:
if Arg='GetWanIP' then
begin
Result:=PChar(SomeFuncThatReturnStr);
end;
SomeFuncThatReturnStr - некоторая функция возвращающая строку - тип string (получение айпишника на самом деле)
А ещё есть программа, где эта либа подгружается и выполняется команда вида lbIP.Caption:=string(ObeyCommands('GetWanIP'));
и значение Caption при этом не меняется, тоесть было оно, скажем, 255.255.255.255 а должно стать 1.2.3.4 (потому что искомый айпи такой), но оно остаётся 255.255.255.255
Как сделать чтобы значение корректно сменялось? Уже весь мозг себе сломал :( Заранее спасибо!
 |
Вопрос задал: MOZGIII (статус: Посетитель)
Вопрос отправлен: 5 января 2010, 21:01
Состояние вопроса: открыт, ответов: 0.
|
Мини-форум вопроса
Всего сообщений: 10; последнее сообщение — 6 января 2010, 21:30; участников в обсуждении: 3.
|
Вадим К (статус: Академик), 5 января 2010, 21:25 [#1]:
"не поменяться" оно может в двух случаях.
- эта строка кода просто не выполняется (например чуточку выше есть if)
- новое значение не отличается от старого. И ничего, что Вы уверенны, что оно должно быть другим. Только логированние подскажет правильный ответ.
Поэтому
- делаем логирование в dll и убеждаемся, что там то, что надо (в простейшем случае можно просто делать запись в файл)
- убеждаемся, что эта строка кода исполняется (ставим точку останова).
- проверяем, что в проект добавлено ShareMem
Галочка "подтверждения прочтения" - вселенское зло.
|
|
MOZGIII (статус: Посетитель), 6 января 2010, 02:34 [#2]:
Тут не бошлось без магии: во-первых строчка кода точно выполняется,а во вторых если рядом поставить ShowMessage(string(ObeyCommands('GetWanIP'))) то он выводит нужное значение...
И даже если использовать tmpvar:=string(ObeyCommands('GetWanIP'));
ShowMessage(tmpvar);
lbTxt.Caption:=tmpvar;
.. значения разные - лейбл не меняется! И ещё, эта конструкция работает и без ShareMem-ов, но у меня используется FastShareMem;
Эх, если бы проблема была так проста... я думаю дело с поинтерами (путаница)
Больше вообще идей нет.
И ещё, там однопотоковый код, мьютексы точно ненужны...
|
|
MOZGIII (статус: Посетитель), 6 января 2010, 02:36 [#3]:
Помогите разобраться, ато придётся много капать асмы и работать дебаггером
|
|
Вадим К (статус: Академик), 6 января 2010, 12:46 [#4]:
Асм тут точно не надо, он не панацея. А вот отладчик - думаю стоит.
Цитата (MOZGIII):
И ещё, эта конструкция работает и без ShareMem-ов
Ну да, работает, чуть код усложниться и наступит ад отладки.
Но раз есть FastShareMem, но все хорошо. Это его заменитель.
"путаницы поинтеров" я тут точно не вижу. На С много программировали?
Текст может не меняться по нескольким причинам.
Например, есть где то таймер, который эту метку постоянно инициализирует старым значением.
Второй вариант - строка возвращается не совсем корректной. Попробуйте выводить не в метку, а например в memo, edit и так далее.
Галочка "подтверждения прочтения" - вселенское зло.
|
|
vlsavkin (статус: 2-ой класс), 6 января 2010, 13:02 [#5]:
Есть подозрение, что все гораздо проще, Вы точно тому label'у передаете строковое значение?
А то lbIP.Caption:=string(ObeyCommands('GetWanIP')); и lbTxt.Caption:=tmpvar; перепутать не могли имя?
|
|
MOZGIII (статус: Посетитель), 6 января 2010, 16:54 [#7]:
Лазил в компиляторе - не помогло
|
|
MOZGIII (статус: Посетитель), 6 января 2010, 17:03 [#8]:
И ещё: если сделать присваивание не string(Value) а string(PChar(Value)), то присваивание происходит, но присваисвается строка без поледнего символа, например "1.2.3." вместо "1.2.3.4"
|
|
Вадим К (статус: Академик), 6 января 2010, 18:21 [#9]:
Настройки компилятора тут точно не помогут. но фраза "лазил в компиляторе - не помогло" - это круто. Работает разработчиком компилятора делфи??? ))
Посмотрел я на код внимательней и думаю, что лучше стоит применить старый известный метод, не изобретать проблему на свою голову. Строковый тип это так называемый magic type - то есть компилятор там вставляет много своего кода на фоне, что бы обеспечить прозрачную работу. А когда мы пытаемся его обмануть, получаем по голове.
Обычно эту проблему решают так. Заводят записи (они же record) вида
type
Answer = record
tip:integer;
end;
AnswerA = record
tip:integer;
rez:string;
end;
AnswerB = record
tip:integer;
rez1:string;
rez2:integer;
код в длл возвращает указатель на одну с таких структур. (его лучше через new создать). в поле tip вписывает число-константу, которое потом вызываемым кодом может использоваться для анализа правильности. А остальные поля заполняет по потребности. Единственное, что бы первое поле всегда занимало 4 байта в каждой структуре для ответа.
Вызываемый код очищает память от структуры вызовом dispose.
Если быть ещё культурней, то структуру должен создавать и передавать вызывающий код, а потом и удалять. (правило - сам создал, сам и чисти).
Галочка "подтверждения прочтения" - вселенское зло.
|
|
MOZGIII (статус: Посетитель), 6 января 2010, 21:30 [#10]:
Сработало, спасибо огромное!
|
Чтобы оставлять сообщения в мини-форумах, Вы должны авторизироваться на сайте.
|