Модераторы: Daevaorn

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> access violation при вызове inflate из zlib.dll, zlib.dll 1.1.3 динамическая линковка 
:(
    Опции темы
boostcoder
Дата 26.2.2012, 00:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



покажи весь код 'CAnotherTestDlg::inf(FILE *source, FILE *dest)'
PM WWW   Вверх
ohos
Дата 26.2.2012, 19:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 31
Регистрация: 13.12.2010

Репутация: нет
Всего: нет



Код

...

#pragma

//указываем какие параметры принимает/возвращает наша импортируемая функция
typedef ZEXPORT int(*inflate_t)(z_streamp, int);
typedef ZEXPORT int(*inflateInit_t)(z_streamp);//, const char *, int
typedef ZEXPORT int(*inflateEnd_t)(z_streamp);


int CAnotherTestDlg::inf(FILE *source, FILE *dest)
{
    CString edittext;
    edit1.GetWindowText(edittext);
    int ret;
    unsigned have;
    z_stream strm;
    unsigned char in[CHUNK];
    unsigned char out[CHUNK];

    strm.zalloc = Z_NULL;
    strm.zfree = Z_NULL;
    strm.opaque = Z_NULL;
    strm.avail_in = 0;
    strm.next_in = Z_NULL;

    //подргружаем нашу dll лежащую в папке экзешника
    HMODULE handle = LoadLibrary("zlib.dll");
   if ( !handle ) {
      //std::cerr << "can`t load library. terminate." << std::endl;
       edit1.SetWindowText(edittext+"can`t load library. terminate.");
      return 1;
   }
   
   inflate_t inf2 = (inflate_t)GetProcAddress(handle, "inflate");
   inflateInit_t infInit = (inflateInit_t)GetProcAddress(handle, "inflateInit_");
   inflateEnd_t infEnd = (inflateEnd_t)GetProcAddress(handle, "inflateEnd");

   if ( !inf2 || ! infInit || !infEnd ) {
       edit1.SetWindowText(edittext+ "can`t get functions addresses. terminate.\r\n" );
      //std::cerr << "can`t get functions addresses. terminate." << std::endl;
      FreeLibrary(handle);
      return 1;
   }
    ret = infInit(&strm); //при запуске ошибка пишется с указанием на эту строку
    //ret = inflateInit2(&strm,15);
    if (ret != Z_OK)
        FreeLibrary(handle);
        return ret;

    do {
        edit1.SetWindowText(edittext+"while 1\r\n");
        strm.avail_in = fread(in, 1, CHUNK, source);
        if (ferror(source)) {
            (void)inflateEnd_t(&strm);
            FreeLibrary(handle);
            return Z_ERRNO;
        }
        if (strm.avail_in == 0)
            break;
        strm.next_in = in;


        do {
            edit1.SetWindowText(edittext+"while 2\r\n");
            strm.avail_out = CHUNK;
            strm.next_out = out;

            ret = inf2(&strm, Z_NO_FLUSH);

            assert(ret != Z_STREAM_ERROR); 
            switch (ret) {
            case Z_NEED_DICT:
                ret = Z_DATA_ERROR;    
            case Z_DATA_ERROR:
            case Z_MEM_ERROR:
                //(void)inflateEnd(&strm);
                (void)infEnd(&strm);
                FreeLibrary(handle);
                return ret;
            }
            have = CHUNK - strm.avail_out;
            if (fwrite(out, 1, have, dest) != have || ferror(dest)) {
                //(void)inflateEnd(&strm);
                (void)infEnd(&strm);
                FreeLibrary(handle);
                return Z_ERRNO;
            }
        } while (strm.avail_out == 0);


    } while (ret != Z_STREAM_END);


    //(void)inflateEnd(&strm);
    (void)infEnd(&strm);

    //FreeLibrary(hDllInstance);
    FreeLibrary(handle);
    return ret == Z_STREAM_END ? Z_OK : Z_DATA_ERROR;
}
...


Это сообщение отредактировал(а) ohos - 26.2.2012, 19:16
PM MAIL   Вверх
boostcoder
Дата 26.2.2012, 19:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



Цитата(ohos @  25.2.2012,  23:57 Найти цитируемый пост)
//убрал тут ", const char *, int", так как судя по zlib 1.1.3 
//эта функция берет только 1 параметр http://koeln.ccc.de/archiv/drt/zlib-manual...ced%20functions

верни обратно потому, что один параметр берет макрос, оборачивающий эту функцию. а макросы не могут экспортироваться. а значит, тебе нужно юзать inflateInit_

так:
Код

ret = infInit(&strm, ZLIB_VERSION, sizeof(strm));
...

PM WWW   Вверх
ohos
Дата 26.2.2012, 20:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 31
Регистрация: 13.12.2010

Репутация: нет
Всего: нет



макрос - это какой-то определенный тип объекта в С++? как вы узнали, что сама функция именно InflateInit_ , а не inflateInit? (просто судя по справке zlib 1.1.3 функция должна была быть inflateInit - http://koeln.ccc.de/archiv/drt/zlib-manual...sic%20functions ), я попробовал сделать как вы указали, предыдущей ошибки не появилось, но вылезла другая :(

Код

В AnotherTest.exe возникло переполнение буфера, что привело к повреждению внутреннего состояния программы. 
Нажмите кнопку "Прервать", чтобы отладить программу, или кнопку "Продолжить", чтобы завершить программу.

Дополнительные сведения см. в разделе "Инструкции по отладке в случае переполнения буфера".


когда запускаю Debug вариант, студия указывает как раз на измененную теперь строку

Код

...
ret = infInit(&strm, ZLIB_VERSION, sizeof(strm));
...


и ругается вроде более понятной ошибкой (только не для меня...)

Код

Run-Time Check Failure #0 - The value of ESP was not properly saved across a function call.  
This is usually a result of calling a function declared with one calling convention with a function pointer declared with a different calling convention.


а почему в импорте функции InflateInit_ второй параметр const char*? если я ничего не путаю, то char это dctuj 1 символ, а в вызове функции мы передаем ZLIB_VERSION, которая объявлена как строка "1.1.3"

Это сообщение отредактировал(а) ohos - 26.2.2012, 20:37
PM MAIL   Вверх
boostcoder
Дата 26.2.2012, 20:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



Цитата(ohos @  26.2.2012,  20:28 Найти цитируемый пост)
макрос - это какой-то определенный тип объекта в С++?

http://www.opennet.ru/docs/RUS/cpp/cpp-5.html

Цитата(ohos @  26.2.2012,  20:28 Найти цитируемый пост)
как вы узнали, что сама функция именно InflateInit_ , а не inflateInit?

декларацию глянул)

Цитата(ohos @  26.2.2012,  20:28 Найти цитируемый пост)
просто судя по справке zlib 1.1.3 функция должна была быть inflateInit - http://koeln.ccc.de/archiv/drt/zlib-manual...sic%20functions

тот мануал дико древний, и в нем серьезное расхождение с действительностью.

Цитата(ohos @  26.2.2012,  20:28 Найти цитируемый пост)
а почему в импорте функции InflateInit_ второй параметр const char*? если я ничего не путаю, то char это dctuj 1 символ, а в вызове функции мы передаем ZLIB_VERSION, которая объявлена как строка "1.1.3"

const char* - и есть строка.

Цитата(ohos @  26.2.2012,  20:28 Найти цитируемый пост)
но вылезла другая

выкладывай компилябельный код.

PM WWW   Вверх
ohos
Дата 26.2.2012, 20:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 31
Регистрация: 13.12.2010

Репутация: нет
Всего: нет



в аттаче

Присоединённый файл ( Кол-во скачиваний: 2 )
Присоединённый файл  AnotherTest2.rar 536,58 Kb
PM MAIL   Вверх
boostcoder
Дата 26.2.2012, 21:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



твой код у меня не скомпилится. нет микрософткомпилятора.
заметил, что ты не задефайнил ZLIB_DLL, хотя я об этом писал несколько постов ранее. по идее в этом проблема.
только не спрашивай где в микрософтстудии дефайнить макросы. я это не знаю.

PM WWW   Вверх
ohos
Дата 26.2.2012, 21:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 31
Регистрация: 13.12.2010

Репутация: нет
Всего: нет



На предыдущей странице нашел

Код

...
#  ifdef ZLIB_DLL
#    if defined(WIN32) && (!defined(__BORLANDC__) || (__BORLANDC__ >= 0x500))
#      ifdef ZLIB_INTERNAL
#        define ZEXTERN extern __declspec(dllexport)
#      else
#        define ZEXTERN extern __declspec(dllimport)
#      endif
#    endif
#  endif  /* ZLIB_DLL */
...


пробовал в свой код вставлять поочередно 

Код

#define ZEXTERN extern __declspec(dllexport)
и
#define ZEXTERN extern __declspec(dllimport)


но это не помогло, ошибка осталась та же (не стал объявлять ZLIB_DLL, а напрямую использовал то, что в нем указано), но сам ZEXTERN у меня уже был объявлен в zlib.h

Код

...
ZEXTERN const char * ZEXPORT zlibVersion OF((void));
...


Это сообщение отредактировал(а) ohos - 26.2.2012, 21:25
PM MAIL   Вверх
boostcoder
Дата 26.2.2012, 21:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



не все члены структуры занулены. потому и ошибка.

сделай так:
Код

   z_stream strm = {0}; // !!!!!!!!!!!!!!!!!!
   int res = infInit(&strm, ZLIB_VERSION, sizeof(strm));


PM WWW   Вверх
ohos
Дата 26.2.2012, 22:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 31
Регистрация: 13.12.2010

Репутация: нет
Всего: нет



не помогло... меня немного смущает вот эта часть ошибки в дебаг версии

Код

calling convention with a function pointer declared with a different calling convention


гугл переводит convention как "соглашение", если я правильно понял, то нужно как-то использовать stdcall (второй вариант не помню) для вызова?
PM MAIL   Вверх
boostcoder
Дата 27.2.2012, 00:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



Цитата(ohos @  26.2.2012,  22:19 Найти цитируемый пост)
не помогло.

не может быть.
без зануления strm у меня вываливалась та же ошибка.


Цитата(ohos @  26.2.2012,  22:19 Найти цитируемый пост)
нужно как-то использовать stdcall

типа того. попробуй методом тыка. я не помню эти соглашения. очень редко использую их.

PM WWW   Вверх
Dem_max
Дата 27.2.2012, 12:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1780
Регистрация: 12.4.2007

Репутация: 4
Всего: 39



Цитата

calling convention with a function pointer declared with a different calling convention


Что то напутано с соглашениями о вызовах функций.


--------------------
Американские программисты долго не могли понять, почему русские при зависании Windоws всё время повторяют "Твой зайка написал" ("Yоur bunnу wrоte")
PM MAIL   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0949 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.