очень запутанный код на С :)

Тема в разделе "LANGS.C", создана пользователем TerraIncognita, 8 авг 2008.

  1. TerraIncognita

    TerraIncognita New Member

    Публикаций:
    0
    Регистрация:
    30 апр 2008
    Сообщения:
    22
    Здравствуйте :)
    случайно вот нашел эту статью:
    http://cbn.narod.ru/elf.html

    и вот там есть вот такой код:

    Код (Text):
    1. #include "E:\ARM\swilib.h"
    2.  
    3. void ElfKiller(void){ // Используется для выхода из эльфа
    4. extern void *ELF_BEGIN;
    5. // здесь обычно еще освобождают память по mfree(), freeWS()
    6. ((void (*)(void *))(mfree_adr()))(&ELF_BEGIN); // Ничего не понятно :(
    7. }
    8.  
    9. int main(char *exename, char *fname){ // Основная функция
    10. // в exename передается путь запущенного эльфа вида 4:\Zbin\xyz.elf
    11. // в fname передается имя файла, который выбран в CardExplorere, вида 0:\Misc\data.txt
    12. // или 0, если elf запущен сам
    13. char *mem;
    14. int i, err;
    15. int handle;
    16. if(fname){
    17. // Работа с файлами стандартна:
    18. handle=fopen(fname,A_ReadWrite+A_BIN+A_Append+A_Create,P_READ+P_WRITE,&err);
    19. // Открыть для чтения и записи в двоичн. режиме с дозаписью (append), создать если нет
    20. // или handle=fopen(fname,A_ReadOnly+A_BIN,P_READ,&err); // только для чтения - константы см. swilib.h
    21. if(handle!=-1){ //-1 = error
    22. mem=malloc(10000); // Выделить память: AllocWS() для строк (по 2б)
    23. if(mem!=0){ //0 = error
    24. i=fread(handle,mem,10000,&err); // Возвращает число прочитанных байт и ошибку в err
    25. // Делаем что-либо makesomebody(mem,i);
    26. fwrite(handle,mem,i,&err);
    27. mfree(mem); // Освободить память: FreeWS() для строк
    28. }
    29. fclose(handle); // Закрыть файл
    30. }
    31. }
    32. SUBPROC((void *)ElfKiller); // се загадка великая есть :) Но без нее низя!
    33. return(0);
    34. }
    35. // PS. Т.к. в x65 файловые чтение и запись проводятся блоками до 32767 байт,
    36. // вместо fread() и fwrite() используем их аналоги fread32() и fwrite32( аналогично)
    37.  
    38. int fread32(int fh, char *buf, int len, unsigned int *err) // (с) Rst7
    39. {
    40. int clen;
    41. int rlen;
    42. int total=0;
    43. while(len)
    44. {
    45. if (len>16384) clen=16384; else clen=len;
    46. total+=(rlen=fread(fh, buf, clen, err));
    47. if (rlen!=clen) break;
    48. buf+=rlen;
    49. len-=clen;
    50. }
    51. return(total);
    52. }
    вот... меня интересует этот урывок:

    Код (Text):
    1. ((void (*)(void *))(mfree_adr()))(&ELF_BEGIN);
    я такого запутанного еще никогда не видел.. может кто-нибудь объяснить, что оно делает и как?

    (void (*)(void *)) - вот это вроде объявляется указатель на ф-ию, возвращающую тип void и принимающую указатель на void... а дальше ниче не понятно...
     
  2. gazlan

    gazlan Member

    Публикаций:
    0
    Регистрация:
    22 май 2005
    Сообщения:
    414
    Одна пара скобок лишняя.
    Вызов функции mfree_adr с параметром &ELF_BEGIN и кэстингом к типу (void (*)(void *); // На самом деле, исходя из объявления ELF_BEGIN, передается void**
     
  3. letopisec

    letopisec New Member

    Публикаций:
    0
    Регистрация:
    8 авг 2004
    Сообщения:
    228
    надо полагать, что mfree_adr() - возвращает адрес некой функции. Он приводится к типу ((void (*)(void *)), и затем функция с этим адресом вызывается с параметром &ELF_BEGIN
     
  4. Necromancer13

    Necromancer13 Виталий

    Публикаций:
    0
    Регистрация:
    26 окт 2007
    Сообщения:
    202
    Адрес:
    Украина, Берегово
    все, пасибки! теперь все ясно :) так и знал, что скобки лишние есть.

    P.S. Случайно не тем аккаунтом залогинился :)