Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > C/C++ программирование > C++ Builder
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 14.06.2010, 19:59   #11
Пепел Феникса
Старожил
 
Аватар для Пепел Феникса
 
Регистрация: 28.01.2009
Сообщений: 21,000
По умолчанию

а вы знаете смещение вашей метки относительно начала ДЛЛ функции?
думаю лучше уж сделать отдельную функцию, чем извращатся(ИМХО подход не удачен)
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
Программа делает то что написал программист, а не то что он хотел.
Функции/утилиты ждут в параметрах то что им надо, а не то что вы хотите.
Пепел Феникса вне форума Ответить с цитированием
Старый 16.06.2010, 18:39   #12
nacgull
Пользователь
 
Аватар для nacgull
 
Регистрация: 17.11.2009
Сообщений: 65
По умолчанию

Цитата:
Сообщение от Пепел Феникса Посмотреть сообщение
а вы знаете смещение вашей метки относительно начала ДЛЛ функции?
думаю лучше уж сделать отдельную функцию, чем извращатся(ИМХО подход не удачен)
Более удачный пример (мой эксклюзив ) :

Код:
//C++ Buider 2009
/-------------------------------------------------------
//  модуль  main.exe
// main_exe.cpp


typedef int (MyClass::* pMethod)(int);


//проверено на практике:
union
{
   pMethod Method;  //12 байт, первые 4 байта = адрес входа в метод класса, декларируем для тестирования

   int var; // адрес перехода на метку  "label:" , 4 байта
};


HINSTANCE hinstDLL = LoadLibrary ("my.dll"); //загрузка DLL
var  = (int)GetProcAddress (hinstDLL, "_Foonc")+3; //получение адреса экспортируемого метода класса ( имитируя адрес переменной )

MyClass Object;

int abc = Object.Foonc(123);


class MyClass
{
   public:
  int Foonc(int a)
  {
       _ЕАХ = var;
        __asm
        {
           jmp eax   // переходим на действительный код метода Foonc
       }
   return a; //для проформы
  }
};
//=========================================
//  модуль  my.dll
// my_dll.cpp


label:  //условно  метка перехода = адрес метода класса, метку можно не ставить - она для удобочитаемости, goto же не применяем :)

extern "C" __declspec(dllexport)  //динамический (явный) экспорт метода 
int MyClass::Foonc(int b)          // точка входа прыжка "jmp eax"
{
   if(b > 0)
  {

   b = (int)&b; 

   } 
   return b;  // возврат в EXE-модуль
}
проверено на практике - прыжок и возврат чистые, позавчера проверил в С++ Билдере-2009

Исходим из того, что при динамическом (явном) экспорте метод класса не экспортируем по стандарту, а только суррогатно как функция, типы
Код:
typedef int (MyClass::* pMethod)(int)

и

typedef int (* pFunction)(int)
не совместимы и RTTI не поможет. Единственное спасение для упрощения работы с DLL - именно "jmp eax", все другие способы "искажают" вызова метода уменьшая читабельность текста проги:
Код:
 Object.Foonc(123)
на, скажем,
Код:
 (Object.*pFoonc)(123)
Имхо, очень упрощает переброску части исходника в DLL, особенно
если классов и методов в классе много. Достаточно прописать в хедере исходника DLL эти "jmp eax", причем через макросы с аргументом, сделать условную компиляцию этой части псевдодекларации класса для вызывающего модуля через
Код:
//-----------------------
//  модуль  my.dll
//my_dll.h

#ifndef def_my_dll 

... //коды декларации пустых методов юзера со вставкой "jmp eax" и иже с ним

#else 

... //коды декларации методов класса для DLL

#endif
(после #else надо декларировать класс для DLL с экспортом через

Код:
__declspec(dllexport) class MyClass
), прописать

Код:
//=====================
//  модуль  my.dll
//my_dll.cpp

#define def_my_dll 
#include my_dll.h
и подключить этот хедер к исходнику главного модуля - без декларации класса с DLL так или иначе не обойтись (компилятор "забанит" ), а использование файлов *.lib и *.obj в динамическом подключении DLL - уж точно извращение.

Кроме того, с двойной передачей параметров (если не использовать "jmp eax", а обычные средства вызова с возвратом) могут возникнуть проблемы - придется разбираться в каждом случае отдельно.

Есть другие простые способы для этого примера?
CPUcode&Asm1801ВМ1,AsmZ80,Asm xPentiumII, Basic,Pascal,Forth,LSL, Delphi,C++,MySQL; web&game prog-ng,code hacking; DreamWeaver,C++Visual&Builder,Photo shop,3Dmax,GoldWaveEditor,Softice..

Последний раз редактировалось nacgull; 17.06.2010 в 10:11. Причина: некорректно прописан код
nacgull вне форума Ответить с цитированием
Старый 16.06.2010, 20:37   #13
coNsept
Форумчанин
 
Аватар для coNsept
 
Регистрация: 14.12.2009
Сообщений: 716
По умолчанию

Цитата:
CPU code & Asm1801ВМ1, AsmZ80, Asm xPentium II, Basic, Pascal, Forth, LSL, Delphi, C++ ; web p-ing, game p-ing, code hacking;DreamWeaver, C++Visual&Builder, Photoshop, 3Dmax, GoldWaweEditor, Softice
Куда столько в тебя лезет ?
coNsept вне форума Ответить с цитированием
Старый 16.06.2010, 22:28   #14
netrino
Участник клуба
 
Аватар для netrino
 
Регистрация: 15.07.2008
Сообщений: 1,933
По умолчанию

nacgull, а можно ещё раз, чего мы этим добились? ИМХО, бред вообще. Минусы на лицо - усложнение читабельности, более высокая вероятность ошибок, а зачем всё это? Если Вас не затруднит, разъясните поподробней выгоду всего этого шаманства )
netrino вне форума Ответить с цитированием
Старый 17.06.2010, 10:50   #15
nacgull
Пользователь
 
Аватар для nacgull
 
Регистрация: 17.11.2009
Сообщений: 65
По умолчанию

Цитата:
Сообщение от netrino Посмотреть сообщение
nacgull, а можно ещё раз, чего мы этим добились? ИМХО, бред вообще. Минусы на лицо - усложнение читабельности, более высокая вероятность ошибок, а зачем всё это? Если Вас не затруднит, разъясните поподробней выгоду всего этого шаманства )
Бред - это по части психиатрии. Кстати доктора рассматривают психику по той же схеме, что и мы компьютер, скажем наведенный бред - что-то вроде зацикливания компа на входные порты.

Шаманство в последнем примере возникло в основном из обще- программистской проблемы экспорта классов с DLL. Когда-то ООП как такового направления не было. Со времени его появления экспорт классов с DLL решили только частично, о чём было сказано в этом примере.

А вот реализация
Код:
goto label
отличается от
Код:
jmp eax
принципами, исповедуемыми языками С++ и Ассемблер.

С++ исповедует блочный принцип вложенности с возвратом через стек. Даже при генерации исключения происходит выход из блока стандартным образом. С
Код:
goto label
то же - переход возможен только в пределах этого или вызвавшего блока, причем компилятор должен знать где поставлена метка. Гуру С++
Код:
goto label
советуют применять для быстрого выхода из глубоко вложенных блоков (если ограничение времени не позволяет применять другой способ).

Ассемблер не ограничен таким принципом, а разрешает всё что угодно - кроме микроассемблирования. С помощью
Код:
jmp eax
можно прыгнуть в любое место адресного пространства.

Но С++ ВКЛЮЧАЕТ в себя часть возможностей Ассемблера как специальное средство для решения задач вроде непредвиденной стандартом компилятора С++ ситуации (ограничение ресурса времени//аппарата). Вспомним, что С++ есть языком промежуточного уровня между высоким и низким (Ассемблер). Специальные средства позволяют значительно увеличить возможности языка относительно реализации программы, но склоняют к связи с аппаратной частью ограничивая таким образом математические, экономические и другие модели, имхо.

//-------------------------------------------------------------
Цитата:
Сообщение от netrino Посмотреть сообщение
nacgull, ...Минусы на лицо - усложнение читабельности ...
Я оцениваю в плюс как улучшение читабельности при переносе значительной части кода с основного модуля во вспомогательный модуль DLL с его преимуществами относительно ресурсов аппаратной части компа. Ухудшение читабельности возникает при замене вызовов методов объектов на суррогатные обращения к DLL, кроме того весомое усложнение - замена ВСЕХ мест с вызовами методов классов DLL - всё это относится к прогам с большим количеством мест с вызовами методов DLL. Естественно при паре-тройке вызовов такое использование ближе к высокому уровню языка - проще применить указатель на метод или переменную класса с DLL нежели ассемблерную вставку.


Резюме.В любом случае указатели на методы DLL надо будет задекларировать и инициализировать - количество этих деклараций равно количеству деклараций при способе помещения jmp eax в псевдодекларацию методов класса. Сложность деклараций примерно равна, а читабельность и переносимость основной части проги со вторым способом выше.

Пожелания. Хорошо бы применить к компилятору плагин исключающий вышеописаную ассемблерную вставку, позволяющий модифицировать оперетор goto и гибко работать с меткой
CPUcode&Asm1801ВМ1,AsmZ80,Asm xPentiumII, Basic,Pascal,Forth,LSL, Delphi,C++,MySQL; web&game prog-ng,code hacking; DreamWeaver,C++Visual&Builder,Photo shop,3Dmax,GoldWaveEditor,Softice..

Последний раз редактировалось nacgull; 17.06.2010 в 13:02.
nacgull вне форума Ответить с цитированием
Старый 17.06.2010, 12:19   #16
nacgull
Пользователь
 
Аватар для nacgull
 
Регистрация: 17.11.2009
Сообщений: 65
По умолчанию

Цитата:
Сообщение от coNsept Посмотреть сообщение
Куда столько в тебя лезет ?
К сожелению, моя подпись ограничена около 250 знаками системы строки подписи

Цитата:
Сообщение от coNsept Посмотреть сообщение
Доброго времени суток уважаемые форумчане!

У меня возник такой вопрос, на который я так и не нашел не одного ответа в googl'e.
Наверно, здесь первый возможный ответ нашелся

Если еще пошаманить - можно с помощью __asm "выдрать" с goto label адрес перехода на метку и поместить его в переменную или регистр проца.
Код:
goto label
в коде эквивалентно примерно
Код:
jmp $00123456
(ближний или дальний прыжок - зависит от оптимизации при конкретном компилировании).

Хорошо бы применить __asm в inline -функции, но увы - мой Билдер банит такое. Придется, в духе ассемблерщика, макрос пялить. Может в настройках проблемка? Кстати, перегрузка оператора goto в Билдере или msVisual C++ допускается?

Цитата:
Сообщение от coNsept Посмотреть сообщение
Без понятий, но по мне так ... *вырезано цензурой*
...
просто не очень хочется использовать goto...
Наверно, хочется использовать С++шную в ставку в Ассемблер.
Когда однажды применить ассемблерную вставку - можно поставить галочку пройденного в ДЕЙСТВИТЕЛЬНОСТИ очередного уровня на трудном пути к званию Гуру С++
CPUcode&Asm1801ВМ1,AsmZ80,Asm xPentiumII, Basic,Pascal,Forth,LSL, Delphi,C++,MySQL; web&game prog-ng,code hacking; DreamWeaver,C++Visual&Builder,Photo shop,3Dmax,GoldWaveEditor,Softice..

Последний раз редактировалось nacgull; 17.06.2010 в 13:29.
nacgull вне форума Ответить с цитированием
Старый 17.06.2010, 16:00   #17
netrino
Участник клуба
 
Аватар для netrino
 
Регистрация: 15.07.2008
Сообщений: 1,933
По умолчанию

Цитата:
Сообщение от nacgull
Бред - это по части психиатрии. Кстати доктора рассматривают психику по той же схеме...
Благодарю, с понятием бреда я знаком )

Цитата:
Сообщение от nacgull
Шаманство... ,имхо.
С матчастью тоже знаком )

Цитата:
Сообщение от nacgull
Я оцениваю...
Да, но читабельность части, написанной на ассемблере куда хуже, более того, если вы неправильно обратитесь по указателю на метод, компилятор выдаст ошибку, а если вы ошибётесь где-то в ассемблерной части, что гораздо проще, то никаких ошибок или даже предупреждений вы не получите. Почему бы для этих целей не использовать интерфейсы? Очень мощное и удобное средство и лишено всех тех недостатков, которые мы обсуждали.
netrino вне форума Ответить с цитированием
Старый 17.06.2010, 16:43   #18
Пепел Феникса
Старожил
 
Аватар для Пепел Феникса
 
Регистрация: 28.01.2009
Сообщений: 21,000
По умолчанию

Цитата:
(ближний или дальний прыжок - зависит от оптимизации при конкретном компилировании).
вообще то ближний полюбому.(у нас прыжок в пределах сегмента, а в Win32 нас в иной сегмент и не пустят.)
а вот уже короткий/длинный это да.

это я к тому что не надо путать понятия
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
Программа делает то что написал программист, а не то что он хотел.
Функции/утилиты ждут в параметрах то что им надо, а не то что вы хотите.

Последний раз редактировалось Пепел Феникса; 17.06.2010 в 16:46.
Пепел Феникса вне форума Ответить с цитированием
Старый 18.06.2010, 17:42   #19
nacgull
Пользователь
 
Аватар для nacgull
 
Регистрация: 17.11.2009
Сообщений: 65
По умолчанию

Цитата:
Сообщение от netrino Посмотреть сообщение
С матчастью тоже знаком )
Но автор темы - не очень

Цитата:
Сообщение от netrino Посмотреть сообщение
Да, но читабельность части, написанной на ассемблере куда хуже,
на ассемблере всего одна команда
Код:
jmp eax
и возможности дает большие, к тому же везде одинаковая (для нашего случая). Можно замаскировать макросом.

Адрес метки можно получить скажем так - ничего ассемблерного:
Код:
Metka_1: int Label( (int)&Label );    
 ... // код юзера для метки
.
.
.
Metka_2: int Label = (int)&Label_2;
 ... // код юзера для метки
Цитата:
Сообщение от netrino Посмотреть сообщение
более того, если вы неправильно обратитесь по указателю на метод, компилятор выдаст ошибку,
выдаст, если записать
Код:
typedef  void (MyClass::* pMethod)();
union
{
   pMethod  Method;
   int adress;
};

HINSTANCE hinstDLL = LoadLibrary ("my.dll"); //загрузка DLL

adress = (int)GetProcAddress (hinstDLL, "_MyMethod"); //получение адреса экспортируемого метода класса ( имитируя адрес переменной) 

MyClass Obj;

(Obj.*ErrorMethod)();
(Obj.*Method)(123);
а вот так не выдаст, и ошибка будет уже в работающей проге:
Код:
int bred = (int)&bred;

typedef  void (MyClass::* pMethod)();
union
{
   pMethod  Method;
   int adress;
};

HINSTANCE hinstDLL = LoadLibrary ("my.dll"); //загрузка DLL

adress = (int)GetProcAddress (hinstDLL, "_MyMethod"); //получение адреса экспортируемого метода класса ( имитируя адрес переменной) 

if(any_predicat) adress = bred;

MyClass Obj;

(Obj.*Method)();
Гарантии, что прогу успеем протестировать, нет. Millenium ошибку-проблему помните?

Цитата:
Сообщение от netrino Посмотреть сообщение
а если вы ошибётесь где-то в ассемблерной части, что гораздо проще, то никаких ошибок или даже предупреждений вы не получите.
Для общего случая да (где много команд ассемблера), но у нас адрес передается в регистр корректно через C++ стандартную переменную _EAX. Если применить макрос (зачем одно и тоже прописывать много раз?) - это будет только в одном месте проги - вероятность ошибки мала.

Цитата:
Сообщение от netrino Посмотреть сообщение
Почему бы для этих целей не использовать интерфейсы? Очень мощное и удобное средство и лишено всех тех недостатков, которые мы обсуждали.
Слышал о таком, но руки пока не дошли до изучения. Можете в двух словах растолковать? Как я понимаю, речь идет об интерфейсе объекта?
CPUcode&Asm1801ВМ1,AsmZ80,Asm xPentiumII, Basic,Pascal,Forth,LSL, Delphi,C++,MySQL; web&game prog-ng,code hacking; DreamWeaver,C++Visual&Builder,Photo shop,3Dmax,GoldWaveEditor,Softice..

Последний раз редактировалось nacgull; 18.06.2010 в 18:32.
nacgull вне форума Ответить с цитированием
Старый 18.06.2010, 17:46   #20
nacgull
Пользователь
 
Аватар для nacgull
 
Регистрация: 17.11.2009
Сообщений: 65
По умолчанию

Цитата:
Сообщение от Пепел Феникса Посмотреть сообщение
вообще то ближний полюбому.(у нас прыжок в пределах сегмента, а в Win32 нас в иной сегмент и не пустят.)
а вот уже короткий/длинный это да.

это я к тому что не надо путать понятия
Oh, I am sorry. Забыл из-за того, что начал заниматься ассемблером x86 раньше, нежели Билл придумал винду32
CPUcode&Asm1801ВМ1,AsmZ80,Asm xPentiumII, Basic,Pascal,Forth,LSL, Delphi,C++,MySQL; web&game prog-ng,code hacking; DreamWeaver,C++Visual&Builder,Photo shop,3Dmax,GoldWaveEditor,Softice..

Последний раз редактировалось nacgull; 18.06.2010 в 18:06.
nacgull вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
goto bye; Ошибка при компиляции в MVS2008 TheWanderer Общие вопросы C/C++ 4 14.06.2010 18:10
goto Serg12 Помощь студентам 12 14.06.2010 17:31
GoTo Diego__ Microsoft Office Word 3 13.03.2010 19:55
чем заменить goto? Agronom Общие вопросы C/C++ 3 19.12.2009 19:43
php goto TDrive PHP 10 28.07.2009 00:04