timochka: Все сообщения за 27 Мая 2003 года

 
ПнВтСрЧтПтСбВс
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31

timochka

опытный

Mishka>>Так, это только у меня так или еще у кого? На месте банера вижу только  "Партнерские программы для развития Вашего бизнеса" и всегда ведет на www.gcl.ru/ - это нормально?
Balancer>Похоже, у тебя только так. Туда только из под баннера ссылочка ведёт - "Globo Clicks - партнерские программы". А баннер - обычно на http://www.dostavkadvd.ru Хотя странно, что только на него, ещё два рекламодателя тоже должны крутиться...




Нет не только у него. Вчера хотел сделать полезное и зайти на сайт спонсора. Тоже самое - всегда ведет Уважаемые партнеры! - gamingpartners.org а там грузится пустая страница. запрещены ActiveX и прочие дырявости.
 

timochka

опытный

>> Кто-нибудь может сказать, подойдёт ли мой усилитель, чтобы открыть полевик? Напряжение открытия от 3 В.
Udjin>Ну дык, побпереть ему затворчик небольшеньким напряжением - делитель из 2 - х резисторов собрать или добавить 2 диодика - г - образная схема, она повышает выходное напряжение примерно на 0,6 вольтика.


Извини. Ты лучше картинкой или более простое объяснение давай. Тут далеко не все знают что такое затвор и где его искать, не говоря уж как делать схему на операционнике. Не почти все могут спаять девайс по простой схеме.
 

timochka

опытный

Serge77>Сегодня купил детали для магнитного датчика апогея:
Serge77>KMZ10A1 - магниторезистивный датчик, $2.5
Serge77>AD8542AR - усилитель, $0.82
Serge77>78L05ACP - стабилизатор питания, $0.15
Serge77>IRF530N - полевой транзистор, $0.65
Serge77>Буду делать по схеме:
Serge77>
Serge77>Потестировал датчик: подал питание 9В, измерял выходной сигнал при разном положении. Напряжение на выходе изменяется от 2 мВ до 14 мВ при переворачивании. Железо чувствует: небольшие предметы - плоскогубцы и т.п. - с расстояния 1-5 см, большие - батарея отопления - с расстояния около 0.5 м. Небольшой магнит и намагниченный пинцет - 10-20 см. В общем, особых ограничений на железо в ракете нет, только совсем рядом не должно быть.
Serge77>Кто-нибудь может сказать, подойдёт ли мой усилитель, чтобы открыть полевик? Напряжение открытия от 3 В.




Совсем не дорого оказывается. Где брал ?

По поводу усилителя не скажу. Но основная идея такая. Усилитель может (теоритически) давать на входе сигнал от -Uпит + 1 вольт до +Uпит - 1 вольт (конкретные цифры на смотреть в справочнике для конкретного усилителя). -Uпит, +Uпит напряжения питания. Тебе надо иметь на выходе сигнал меняющийся от 1.5 вольт до 4 вольт, для простоты и надежности. На входе при этом меняется с 5 мВ до 10 мВ (загрубленно).
коеффициент усиления схемы = (4 - 1.5) / (0.010 - 0.005) = 500 раз.
Для операционного усилителя это не много. Пойдет почти любой. Теперь надо подобрать модель усилителя исходя из напряжения питания (9 Вольт на ракете самое то. Если ставить стабилизатор питания, то он отъест 2 Вольта примерно).
Поскольку требования не крутые, то думаю что подойдет если питания ему хватит. А почему ты брал именно этот усилитель ?
 

timochka

опытный



timochka>>Теперь переименовываем файл Mylib2.dll в Mylib1.dll и снова запускаем.
timochka>>Видим "Я класс MyClass2." - Но ведь мы ничего не пересобирали! Значит на лицо динамическое связывание.
Balancer>Таки, ИМХО, это всё равно статическое связывание. Оно происходит при линковке программы, а не при её исполнении. DLL - это всего лишь продвинутая отложенная линковка. Хотя, могу и ошибаться. Но пример ещё не убедительный :)


Dll это динамическая библиотека. Я могу загрузить ее по имени и получить указатель на функцию ПО ИМЕНИ ФУНКЦИИ. И огребу граблей при возове если не положу аргументы таким образом как хочет функция.



К сожалению, у меня нет под рукой VC++, сделай, плиз, ассемблерный листинг вызова виртуальной функции - тогда и будет всё ясно :)


Кстати, вот ещё такая фишка. Динамическое связывание возможно только при наличии пространства имён, включённого в код готовой программы. А это автоматически подразумевает возможность вызова функции по её имени, полученному во время исполнения программы.

А вот и не угадал. Все виртуальные функции класса нумеруются, а в классе заводится таблица виртуальных функций vtable. Там лежат указатели на РЕАЛИЗАЦИЮ данного метода в этом классе. И все вызовы виртуальных функций идут через таблицу. Т.е. класс тащит с собой указатели на собственные методы.

Т.е. невозможно вызвать метод по его символьному ИМЕНИ, но вполне можно вызвать если знаешь позицию метода в vtable. Именно так и работает с СОМ модулями писаными на С++ не объектные языки (ассемблер например).



Mishka> А что еще добавить - Рома не прав, но не в том, что летчиков, а в том, что динамическое связывание было и есть в С++, а уж в Джаве можно точно вызвать метод из любого объекта.

>Но в C++ - приведите мне ассемблерный кусок, показывающий именно динамическое связывание - я поверю :)


Да нет, бред это! Ну не умеет C++ работать с незнакомыми ему классами! Пусть у нас суперкласс не имеет нужной виртуальной функции. Тогда, чтобы её вызывать, как в постинге с примерами, что привёл timochka при добавлении её в субкласс, мы обязаны прописать её в суперкласс и перекомпилить dll с суперклассом. И это - динамическое связывание?? Зачем нам тогда перекомпиляция? :D


Не иметь прототипа в базовом классе это все равно что не знать ее имени. Ты не обязан знать ее реализацию ( func() =0 как раз и обозначает абстрактную функцию) Но надо указать ее смещение в таблице виртуальных функций и типы аргументов + тип возвращаемого значения.

А на ассемблере будет конструкция типа call classInstance.vtable[XXX]

Может тебя Рома такой кусок убедит.

class IMyInterface
{
public:
virtual void WhoIam(void) =0;
};

class MyClass1 : public IMyInterface
{
public:
virtual void WhoIam(void) { MessageBox(0l, "Я класс MyClass1", "Info", MB_OK); };
};

class MyClass2 : public IMyInterface
{
public:
virtual void WhoIam(void) { MessageBox(0l, "Я класс MyClass2", "Info", MB_OK); };
};

class MyClass33 : public MyClass2
{
public:
virtual void WhoIam(void) { MessageBox(0l, "Я класс MyClass33", "Info", MB_OK); };
};

IMyInterface GetInterface(void)
{
IMyInterface *pIntance = 0l;

switch (clock() % 3) // часы как датчик случайных чисел. Криво но так проще.
{
case 0:
pIntance = new MyClass1();
break;
case 1:
pIntance = new MyClass2();
break;
case 2:
pIntance = new MyClass3();
break;
}

return *pInstance;
}


// И гдето в нашей проге делаем такую шутку
for (int i = 0; i < 10; ++i)
{
GetInterface().WhoIam();
Sleep(100);
}
 
Это сообщение редактировалось 27.05.2003 в 16:41

timochka

опытный

varban>[QUOTE]
Accept>>>ибо этиленгликоль голубой
Balancer>>Чистый этиленгликоль, как и его водные растворы - бесцветный.
varban>[/QUOTE]
varban>Все чистые вещества либо прозрачные, либо белые (с)
varban>:D :D
varban>[i]

Эх люди, а вы не думали что ЦВЕТОМ антифриза (тосола) обозначается температура его замерзания. И ничего удивительного что в Африку его другой поставляют. У них в Африке мороз тоже Африканский. Я на банках даже цветовую шкалу видел. Кстати тосол зеленоватый в СССР был. Сейчас может у каждого производителя своя шкала быть. :(
 

timochka

опытный



>Mishka>Я чай сладкий пью только с соленным или кислым (контраст вкусов) - а так всегда без сахара. Зеленый не пью с сахаром вообще.


Ага. У меня такой же подход :)


А я его завариваю так что сахаром его не сластить, а закусывать надо. Ибо крепок!
 

timochka

опытный

termostat>


Продукция компании International Rectifier


Продукция компании International Rectifier

// www.platan.ru
 
>
Serge77>Действительно, там есть такие, что и при 1 В открываются. А мой с 4В начинает открываться, наверное его компаратор не откроет.
Serge77>А почему нужен именно полевик? Тиристор не пойдёт?




Полевик имеет очень малое сопротивление в открытом состоянии = малые потери. И его можно легко выключить - просто убрали напряжение с затвора и он закрылся. А тиристор требует убрать ПИТАЮЩЕЕ напряжение (не только управляющее) для того что-бы закрыть = больше гемороя.
 

timochka

опытный

timochka>> Полевик имеет очень малое сопротивление в открытом состоянии = малые потери. И его можно легко выключить - просто убрали напряжение с затвора и он закрылся.
Serge77>Малое сопротивление - это конечно хорошо, но насколько у тиристоров оно больше?
Serge77>А выключать ничего не надо, у меня цепь будет размыкаться физически при отделении головной части.




Размыкать надо иметь возможность. если запал за 3 секунды не сработал не фиг батарею сажать, надо резервный пробовать. А вообще переделать проще будет когда что-нить другое придумаешь.

Во скока раз сопротивление больше - не знаю. Знаю что больше и что поэтому полевики предпочитают при конструировании. Тут спеца надо спрашивать.
 

timochka

опытный

Рома, я заметил что ты последнее время редактор сообщений совершенствуешь.

Можно для не любителей визуального редактора такую фичу сделать - когда свое сообщение редактируешь или на чужое отвечаешь видишь вместо переводов строк (br). Откуда это берется мне ясно. Но можно чтоб в окне всеже переводы строк видны были , а не тег (br). Тем более что если ручками (br) на перевод строки заменяешь то все все равно работает отлично.

Если будешь еще в редакторе ковыряться сделай заодно и эту замену - если конечно время найдешь.
 

timochka

опытный

>timochka>>Размыкать надо иметь возможность. если запал за 3 секунды не сработал не фиг батарею сажать, надо резервный пробовать.
Serge77>Это можно будет сделать, когда все датчики будут на контроллере сидеть. А пока я делаю простейшую схему.

Дык ты потом контроллер к ней-же прикручивать будешь для попробовать.

Serge77>Кстати тиристоры тоже можно закрывать, если подать обратное напряжение (если я не ошибаюсь).


Вроде это их не закрывает, насколько я помню. Короче помним мы разное и нужно звать спеца для консультации.
 

timochka

опытный



timochka>> GetInterface().WhoIam();


Ну и ругается он на эту строку: error C2259: 'IMyInterface' : cannot instantiate abstract class due to following members: 'void IMyInterface::WhoIam(void)' : pure virtual function was not defined test.cpp(6) : see declaration of 'IMyInterface::WhoIam' :)


Это захотел я код глянуть... Ну уверен я, что он статический будет :)



Извини наврал в исходнике.

IMyInterface *GetInterface(void)
{
IMyInterface *pInstance = 0l;

switch (clock() % 3) // часы как датчик случайных чисел. Криво но так проще.
{
case 0:
pInstance = new MyClass1();
break;
case 1:
pInstance = new MyClass2();
break;
case 2:
pInstance = new MyClass3();
break;
}

return pInstance;
}

void main(void)
{
// И гдето в нашей проге делаем такую шутку
for (int i = 0; i < 10; ++i)
{
GetInterface()->WhoIam();
Sleep(100);
}

}

На асме кусок выглядит так (шоб я что-то понял)

; 53 : // И гдето в нашей проге делаем такую шутку
; 54 : for (int i = 0; i < 10; ++i)

$L54788:

; 55 : {
; 56 : GetInterface()->WhoIam();

call ?GetInterface@@YAPAVIMyInterface@@XZ ; GetInterface
mov edx, DWORD PTR [eax]
mov ecx, eax
call DWORD PTR [edx]

; 57 : Sleep(100);

push 100 ; 00000064H
call edi
dec esi
jne SHORT $L54788
pop edi

; 58 : }
; 59 :
; 60 : }


Могу сорец выложить.
 

timochka

опытный



>Я всё не могу чётко сформулировать, свою мысль на счёт свзывания. Ещё раз повторю такой пример. На C++ ты в суперклассе обязан указать все виртуальные функции. Ты не можешь из него вызывать функции, имена и интерфейсы которых на момент его компиляции ещё не определены. Это и есть одно из отличий статического и динамического связывания. При статическом - ты всё должен знать заранее. И для введения какого-то нового метода, общего для всех субклассов, ты должен перекомпилить суперкласс. Что невозможно, например, при расширении, скажем, коммерческой софтины частными DLL (только один из примеров). Скажем, есть у тебя программа A. Коммерческая, закрытая. Есть у неё API для пользовательских DLL. И по этому API все пользовательские DLL - это классы, наследники API-шного суперкласса. Всё хорошо, но в C++ с этого момента пользовательские расширения ограничены виртуальными методами суперкласса. И наследник расширения Б не может вызвать метод расширения В без введения этого метода в суперкласс API А. Да, расширение В, например, может слепить свой API и предоставлять его расширению Б. А если в другой раз захочется то же самое вызвать для расширения Г? В общем, получается, что всё равно ещё на этапе компиляции нужно знать всё обо всём, что там будет в дальнейшем. Что в реальных задачах не так уж редко нереально.


А в той же Java (как тут Lerm отмечает, я сам не пользовался этим) я могу рискнуть вызвать метод другого класса, даже если на этапе компиляции моей программы про тот метод ещё не было известно.



Это все от того что С++ при динамическом связывании оперирует не символьными именами, а номерами методов. То есть в пределах одного дерева наследования компилер раздает всем виртуальным методам номера (они же смещения в таблице vtable). Естессно чтоб коректно раздать номера надо знать про все методы. В принципе ты можешь на низком уровне вызвать метод по номеру произвольно. То есть ты знаешь что у класса указатель на который тебе дали есть 10 виртуальных методов. Можешь дернуть все 10 методов сам. Но это дурной тон из соображений переносимости. Плюс если тебе дадут указатель который будет указывать на экземпляр имеющий только 5 методов, а попытаешься дернуть 10-й то программа рухнет. Поэтому требования иметь описания всех интерфейсов заранее это компромис для безопасности. Тем самым компилер проверяет за тебя корректность кода.

А низкоуровневый вызов выглядит чем-то типа
code text
  1. <font size=1>Created with colorer-take5 library. Type '[b]cpp[/b]'</font>
  2.  
  3. pInstance<span style='color:#808030; '>-</span><span style='color:#808030; '>></span>vtable<span style='color:#808030; '>[</span><span style='color:#008c00; '>10</span><span style='color:#808030; '>]</span><span style='color:#808030; '>(</span><span style='color:#808030; '>)</span><span style='color:#800080; '>;</span> <span style='color:#696969; '>// вызвать 11-й виртуальный метод</span>

Только учти что член класса vtable имеет атрибут private.
 

в начало страницы | новое
 
Поиск
Настройки
Твиттер сайта
Статистика
Рейтинг@Mail.ru