|
|
| Посл.отвђт | Сообщенiе |
|
|
Дата: Авг 29, 2003 06:49:55 volodya Теперь всё ясно. Попробую заполнить этот массив статически (раз можно на асме, можно и на С). Слушай, а зачем тебе qsort? Массив-то можно отсортировать заранее (в самих сорсах). Кстати, CRC32 быстрее подсчитывать с помощью таблицы. Сейчас высплюсь и завтра поизвращаюсь над C :) |
|
|
Дата: Авг 29, 2003 07:58:34 · Поправил: Artem Можно сделать все вызываемые функции такого типа: int (*)(const void* InBuf,int InSize,void* OutBuf) (возвращается размер записанных в OutBuf данных). А копмилятор будет сам определять размер указателя в зависимости от платформы. |
|
|
Дата: Авг 29, 2003 11:52:34 Я бы посоветовал использовать уже давно проверенные подходы к решению задач подобного типа. А именно использовать функции какого-нибудь компилятора для работы с таблицей символов. Обычно там используют примерно такой подход. Берут некую простенькую (хеш?) функцию, которая допускает коллизии. К примеру она может просто складывать все символы в имени подпрограммы по модулю 256. Далее для всех функций считается этот хеш и создается таблица указателей. Каждый элемент таблицы соответствует некоторому множеству функций, которые имеют данный хеш. Указатели в таблице указывают, например на массив, который содержит имена функций с данным хешем. Для поиска нужной функции мы считаем ее хеш. Далее, используя его в качестве индекса в таблице получаем указатель на массив, который содержит имена всех функций с данным хешем (а таких функций из 300 может быть всего 10). И далее просто просматриваем этот массив в поисках информации о нужной нам функции. Т.е. получается, что этот хеш с коллизиями как бы делит все множество функций на небольшие подмножества, так что поиск нужного нам подмножества и конкретной функции в нем занимает гораздо меньше времени, чем перебор всех функций. Тут все зависит от выбранной функции (она должна как можно равномернее делить множество функций на подмножества). Та, которую привел я довольно хреновая, это только иллюстрация. Вообще, чувствую, я довольно дико все объяснил. :) Но ты почитай любую книжку по теории компиляторов, раздел, где рассматриваются таблицы символов. Кстати, я недавно тебе реквест на одну такую книгу присылал. ;) В дракончике это точно есть. Только там напряг с конкретной реализацией будет. Да, насчет параметров к функции ничего посоветовать не могу, т.к. я пока не понял, откуда эти параметры беруться. |
|
|
Дата: Авг 29, 2003 12:57:32 IMHO, в данном случае достаточно использовать бинарный поиск имен, врядли имен будут тысячи, так что использовать хэшы не логично, а по отсортированным таблицам поиск будет очень быстрым. Беите пример с таблицы экспорта. Вот. |
|
|
Дата: Авг 29, 2003 16:57:25 Если таблица соответствий функция -- адрес постоянна, то можно упортебить бинарный поиск. Один из таких алгоритмов (кстати для XASM) у меня лежит под названием Однонаправленный древовидный словарь. Тут так же может употреблятся хеширование.. Но я им не пользуюсь... Структура древовидного словаря. (Для Асма я использую её оптимизированный вариант, для С я это опускаю) Древовидный словарь представляет собой совокупность блоков символов, где каждый блок -- это положение символа в слове. Блоки имеют разный формат, в зависимости от назначения Вот типичный Формат блока - это список: [код символа][указатель][код символа][указатель] То есть каждому коду символа соответствует указатель на другой блок. И так далее, пока не кончится словарь. Теперь подробней. Понятно, что в словаре содержится несколько слов. Предположим, что есть несколько слов на первые "a" на "b" вторые, третие в слове... Тогда будет несколько веток на "a" на "b" А начале блока идёт байт флагов. Если он = 0, то значит больше ветвлений нет, и остальные байты -- это символы, которые остались. Если не ноль -- значит идёт ветвление и это символ. Если == 1 значит это не ветвление а например адрес функции... Извините, но дописывая эти строки я бегуууу..... |
|
|
Дата: Авг 29, 2003 17:59:08 Ребята, спасибо, конечно вам всем за ответы. Тут же никто и не спорит. Только к компилятору привязываться никто не будет - это компиляторо-зависимо - я же говорил, код будет компилироваться минимум под 3-4 осями - а это значит cl/gcс/черт в ступе и т.д. Самое важное - НИКТО ТАК И НЕ СКАЗАЛ, что делать ПОСЛЕ того, как я нашел хеш, имя или что-то там еще. Сейчас мне реально видится только одна вещь:
hugefunction(char *func_name)
{
switch(strCRC(func_name))
{
case(12345)
do_this();
break;
case(45769)
do_that();
break;
//и т.д.
}
}
Я не скажу, ни что это элегантно, ни действительно быстро, но это будет работать под любой осью и что бы там функция не вернула - список, массив, int, указатель на char, опять таки, черта в ступе... Разумеется, вариант с массивом, который отсортирован и бинарным поиском в нем звучит классно, но как туда положить адрес функции - это пытался сделать только Quantum, да и то... |
|
|
Дата: Авг 29, 2003 18:00:49 Sten Да, написано диковато, если честно. Общую канву можно ухватить только после того, как почитал статью на RSDN по хещированию и применению хеша в качестве индекса. А потом выстраиваются односвязанные списки, да... Тут представляю... Но ЧТО мне хранить в тех списках... |
|
|
Дата: Авг 29, 2003 21:28:17 volodya Может я что-то не так понял, но нельзя ли сделать так, За именами функций закрепить номер и Получаем имя функции определяем ее номер суем в eax и делаем так:
call dword ptr func_name[eax*4]
jmp ....
func_name dd offset func1, offset func2
dd offset funk3, offset func4
|
|
|
Дата: Авг 29, 2003 21:58:59 KiNDeR Оптимизирующий компилятор под Intel-архитектуру даст тебе точно такой же код для switch/case. И это будет платформенно-независимо. Правда, если честно, я не знаю, будет ли что-то похожее под солярисовским асмом - там же RISC :( |
|
|
Дата: Авг 29, 2003 22:09:13 volodya Ну тады извеняй, что то ближе к сентябрю я за собой замечаю, что начинаю притормаживать... |
|
|
Дата: Авг 29, 2003 22:42:38 KiNDeR Да за что извинятся! Ты помочь хотел. Наоборот, спасибо! |
|
|
Дата: Авг 29, 2003 22:43:53 volodya :-) |
|
|
Дата: Авг 29, 2003 23:00:19 volodya но как туда положить адрес функции - это пытался сделать только Quantum, да и то... Сорри, только что с работы вернулся :) Так вот: #include <stdio.h>
// Define all protos:
void f0(char*); // 'f' + '0' = 102 + 48 = 150
void f1(char*); // 151
void f2(char*); // 152
void f3(char*); // 153
void f4(char*); // 154
void f5(char*); // 155
void f6(char*); // 156
void f7(char*); // 157
void f8(char*); // 158
void f9(char*); // 159
void call(char*);
typedef void function (char*);
struct token{
int hash;
function *address;
};
token hashtable[] = {
{150,f0},{151,f1},{152,f2},{153,f3},{154,f4},
{155,f5},{156,f6},{157,f7},{158,f8},{159,f9},
{0,0} // <- GND
};
// calculate checksum and call corresponding function
void call(char* name){
int checksum = 0;
// calculate checksum
while(*name) checksum += *(name++);
// parse hashtable
for(token *cursor = hashtable; cursor->hash; cursor++)
if(cursor->hash == checksum)
// finally call that function
cursor->address("test");
}
int main(int argc, char* argv[]){
call("f0");
call("f9");
call("f5");
return 0;
}
void f0(char* param){ printf("f0: %s\n", param); }
void f1(char* param){ printf("f1: %s\n", param); }
void f2(char* param){ printf("f2: %s\n", param); }
void f3(char* param){ printf("f3: %s\n", param); }
void f4(char* param){ printf("f4: %s\n", param); }
void f5(char* param){ printf("f5: %s\n", param); }
void f6(char* param){ printf("f6: %s\n", param); }
void f7(char* param){ printf("f7: %s\n", param); }
void f8(char* param){ printf("f8: %s\n", param); }
void f9(char* param){ printf("f9: %s\n", param); }
Я тут использовал тупой парсинг всего массива, но организовать бинарный поиск не составит особого труда (у тебя, наверное, уже есть готовый код). Ну, и CRC я поменял на обычную сумму... спешил :) |
|
|
Дата: Авг 30, 2003 00:01:47 · Поправил: volodya Quantum Сперва нескомпилилось. Ща поправил и разбираюсь. typedef void function (char*); - ну и? Функция может быть только void? А если нет? А если и char * она не будет принимать, а, скажем, int? Или что-то вроде ValNodePtr? В общем и в частности, насколько я догоняю. Проблема не может быть решена для общего случая на С, лишь для частных случаев. На С++ - возможно, я пока еще там плаваю. Может что-то вроде шаблона... Не знаю... На асме - понятное дело. Так что остается: switch/case с хорошей hash-функций БЕЗ коллизий, вероятно, CRC32 со строки на С. |
|
|
Дата: Авг 30, 2003 00:28:18 http://www.function-pointer.org/ - турториал по указателям на функции. Нельзя объявить указатель хрен знает на что. Поэтому switch/case - это единственное, что можно предложить, вероятно. Вот и усе :(((( |
|
Powered by miniBB 1.6 © 2001-2002
Время загрузки страницы (сек.): 0.081 |