Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Общие вопросы > Не хочет выполняться функция из DLL


Автор: Nemesis 3.4.2007, 11:14
Доброго дня!

У меня возникла проблемка с импортом функций из DLL. Первая функция InitAVILibrary  срабатывает без проблем, а вот следующая с параметрами  InitAVIMemory(TPPAVI ppAVI) выдает ошибку  Access violation reading location 0x00000000.
По идее в метод я просто посылаю указатель ppAVI и он после выполнения функции указывает мне куда нужно...

Код

#include <windows.h>

typedef unsigned int uint;
typedef void* Pointer;
typedef uint* PCardinal;
typedef char* PChar;
typedef PBITMAPINFO* TPPBITMAPINFO;
typedef Pointer* TPPAVI;

//-------------------------------Объявление функций из AviDll.dll-------------------------------
typedef void (*INITAVILIBRARY)();
INITAVILIBRARY InitAVILibrary;
typedef void (*RELEASEAVI)();
RELEASEAVI ReleaseAVILibrary;
typedef int (*INITAVIMEMORY)(TPPAVI ppAVI);
INITAVIMEMORY InitAVIMemory;
typedef void (*FREEAVIMEMORY)(TPPAVI ppAVI);
FREEAVIMEMORY FreeAVIMemory;
typedef int (*OPENAVIFORREAD)(Pointer pAVI, PChar FileName, PCardinal stFrame, PCardinal numFrames);
OPENAVIFORREAD OpenAVIForRead;
typedef int (*CLOSEAVIFILE)(Pointer pAVI);
CLOSEAVIFILE CloseAVIFile;
typedef int (*AVIFRAMECAPTURE)(Pointer pAVI, uint Frame, TPPBITMAPINFO ppDIB);
AVIFRAMECAPTURE AVIFrameCapture;
//----------------------------------------------------------------------------------------------

HINSTANCE dllInstance;
TPPAVI ppAvi;
Pointer pAVI;
PCardinal stFrame, numFrames;

int main()
{
    dllInstance = LoadLibrary("AviDll.dll");

    //-------------------------------Импорт функции из AviDll.dll-------------------------------
    InitAVILibrary = (INITAVILIBRARY)GetProcAddress(dllInstance, "InitAVILibrary");
    ReleaseAVILibrary = (RELEASEAVI)GetProcAddress(dllInstance, "ReleaseAVILibrary");
    InitAVIMemory = (INITAVIMEMORY)GetProcAddress(dllInstance, "InitAVIMemory");
    FreeAVIMemory = (FREEAVIMEMORY)GetProcAddress(dllInstance, "FreeAVIMemory");
    OpenAVIForRead = (OPENAVIFORREAD)GetProcAddress(dllInstance, "OpenAVIForRead");
    CloseAVIFile = (CLOSEAVIFILE)GetProcAddress(dllInstance, "CloseAVIFile");
    AVIFrameCapture = (AVIFRAMECAPTURE)GetProcAddress(dllInstance, "AVIFrameCapture");
    //------------------------------------------------------------------------------------------

    InitAVILibrary();
    int result = InitAVIMemory(ppAvi);
    OpenAVIForRead(pAVI, "Lexx12.avi", stFrame, numFrames); 
    CloseAVIFile(pAVI);
    FreeAVIMemory(ppAvi);
    ReleaseAVILibrary();

    FreeLibrary(dllInstance);

    return 0;
}

Автор: threef 3.4.2007, 13:33
так проверь, почему getprocadr возвращает тебе 0.Имя там, фамилия...

Автор: zkv 3.4.2007, 15:39
Цитата(Nemesis @  3.4.2007,  11:14 Найти цитируемый пост)
а вот следующая с параметрами  InitAVIMemory(TPPAVI ppAVI) выдает ошибку  Access violation reading location 0x00000000.

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

Автор: Nemesis 3.4.2007, 16:51
threef, забыл сказать, адреса на все функции берутся нормально, 0-ых нету. 


zkv, пробовал выделять память но не помогает:(

DLL написана на Delphi, вот заголовочный:

Код

type
  TPPAVI = ^pointer;
  TPPBITMAPINFO = ^PBITMAPINFO;
  TNumHypoExtArray=array of TNumHypoExt;
  PNumHypoExt=^TNumHypoExt;

procedure InitAVILibrary; cdecl; external LibAVI;
procedure ReleaseAVILibrary; cdecl; external LibAVI;
function  InitAVIMemory (ppAVI:TPPAVI):integer; cdecl; external LibAVI;
procedure FreeAVIMemory (ppAVI:TPPAVI); cdecl; external LibAVI;
function  OpenAVIForRead (pAVI:pointer; FileName:PChar; stFrame,numFrames:PCardinal ):integer; cdecl; external LibAVI;
function  CloseAVIFile( pAVI:pointer ):integer; cdecl; external LibAVI;
function  AVIFrameCapture (pAVI:pointer; frame:cardinal; ppDIB:TPPBITMAPINFO):integer; cdecl; external LibAVI;



больше никаких сведений. Как быть с этим добром?

Автор: threef 3.4.2007, 17:11

function  InitAVIMemory (ppAVI:TPPAVI):integer; cdecl; external LibAVI;

typedef int (*INITAVIMEMORY)(TPPAVI ppAVI);

1. Попробуй добавить __cdecl
2.-,,-    extern "C" перед всеми обьявлениями типов.

Автор: Earnest 3.4.2007, 18:51
Цитата(threef @  3.4.2007,  18:11 Найти цитируемый пост)
Попробуй добавить __cdecl

скорее наоборот, stdcall: cdecl и так по-умолчанию, а раз дельфи, то скорее там паскалевские соглашения...

Автор: threef 3.4.2007, 20:17
Earnest
function  InitAVIMemory (ppAVI:TPPAVI):integer; cdecl; external LibAVI;

Добавлено @ 20:19
__cdecl не по умолчанию, С++ имеет свои соглашения об именах
это я глупость сморозил, извините, но все-таки стоит проверить опцию /Gd
А если не получится - пробовать тот же __stdcall, __fastcall :
Microsoft Specific

The __pascal, __fortran, and __syscall calling conventions are no longer supported. You can emulate their functionality by using one of the supported calling conventions and appropriate linker options. 

WINDOWS.H now supports the WINAPI macro, which translates to the appropriate calling convention for the target. Use WINAPI where you previously used PASCAL or __far __pascal. 

END Microsoft Specific


Автор: Nemesis 5.4.2007, 18:01
Простите, не совсем пойму, куда мне вставить все эти штуки __stdcall, __fastcall или __cdecl? 
extern "C" вставил, но не помогло...
Мне кажется проблема тут именно в том, что передается в функции, а не в функциях. Первая нормально срабатывает, а вот с параметрами отказываются.  smile 

И еще, я что-то не пойму, в заголовке Дельфи след:

TPPAVI = ^pointer;
function  InitAVIMemory (ppAVI:TPPAVI):integer; cdecl; external LibAVI;

Если в функцию передается нетипизированный указатель на указатель, то как я могу выделить под него память?

Автор: zkv 5.4.2007, 18:42
Цитата(Nemesis @  5.4.2007,  18:01 Найти цитируемый пост)
Если в функцию передается нетипизированный указатель на указатель, то как я могу выделить под него память? 

выделить то не проблема, непонятно куда и сколько, можно только гадать, стоит  поискать пример использования на том же Дельфи.
интересный тип TPPAVI, видимо также существует тип TAVI? Неизвестно, что он из себя представляет? Видимо какая то структура,  в любом случае вам надо будет найти информацию по этому вопросу, ведь не получится работать вслепую?

Автор: Earnest 6.4.2007, 09:45
Да, насчет cdecl не заметила.
Действительно, похоже, что дело в параметрах.
Объявление действительно выглядит так, что IniAVIMemory сама выделяет память и записывает в параметр...

А! попробуй так:

Код

pointer pAVI = 0;
InitAVIMemory (&pAVI);


Понимаешь разницу?

Автор: Nemesis 8.4.2007, 16:52
Earnest, да, спасибо, проблема была именно в этом. Нужно было просто посылать нормальный указательsmileа не пустой... 

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)