[ANSI C][Asembler] ładowanie funkcji asemblerowych z DLL

0

Cześć.

Mam program napisany w C do którego dodaje standardowo DLLke dołączaną dynamicznie. Zrobiłem to poprzez stworzenie dwóch projektów w solucji, jeden z główną aplikacją, drugi jako DLL. W DLL stworzyłem defa, asma itd.
Projekt główny aplikacji to projekt konsolowy napisany w C.

Dllka kompiluje się dobrze, do głównej aplikacji załączam ją w ten sposób:

 typedef void (*MYPROC1)(DWORD); 
    DWORD blad; 
    MYPROC1 TabWe; 
    HMODULE hLib; 
    hLib = LoadLibrary(TEXT("bibliotekaDll.dll")); 
    blad = GetLastError(); 
    if (hLib != NULL) 
    { 
        TabWe = (MYPROC1)GetProcAddress (hLib,"TabWe"); 
        if (TabWe != NULL) 
            TabWe(2); 
        FreeLibrary (hLib); 
    }

Gdy wywołuje się dowolną funkcję z Dllki która nie przyjmuje żadnych argumentów, wszystko działa poprawnie, debugger przechodzi przez funkcje i wszystko gra, lecz jeżeli wywoła się dowolną funkcję która przyjmuje dowolny argument to wysypuje się przy powrocie do C. Wyskauje następujący błąd:

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.

Przy powrocie do C czyli gdy debugger przejdzie przez całą funkcję asemblerową i gdy ma przejśc do następnego statementu w C.

Wujek google niedużo mi powiedział na ten temat, wspominał coś o zmianie opcji ładowania biblioteki z Unicode na Ansi. Sprawdziłem obie możliwości zmian w opcjach projektu wraz z próbą ładowania biblioteki funkcjami LoadLibraryA i W i nie dało to rezultatów.

Chciałem też zaznaczyć, że funkcja TabWe nic nie robi z podanym argumentem, po prostu ma go podanego. Kod funkcji wygląda tak (po usunięciu zakomentowanych linii)

 TabWe proc tab: DWORD 
       ret 
TabWe endp

Ktoś ma może jakiś pomysł jak mi pomóc? Z góry wielkie dzięki.

Używam VS 2008.

0

Musisz mieć pewność, że obie funkcje poza zadeklarowanymi parametrami mają tę samą konwencję wywołania (jak funkcja działa niskopoziomowo), jeśli tego nie podzasz używana jest domyślna (konfigurowana) konwencja.
Po obu stronach (app + DLL) przy deklaracji funkcji określ konwencję np. __stdcall

czyli w app w deklaracji:

typedef void (__stdcall *MYPROC1)(DWORD);

a w DLL:

void __stdcall TabWe(DWORD)
{
  //...
}

Co się tyczy UNICODE, to też może być problem, w ogóle to nie polecam używać WCHAR (czyli typu zależnego od ustawień kompilatora) w pliku nagłówkowym połaczanym do kilku solucji (nagłówek DLLa), kiedyś w projekcie zmieniłem sobie w ustawieniach UNICODE i potem nie wiedziałem o co chodzi, czemu wypluwa mi głupoty w tekście, dopiero po kilku h analizy doszedłem do tego :>

Dodatkowo w przypadku C++ i DLLi trzeba pamiętać o extern "C" żeby oddekorować nazwę + __declspec(dllexport), żeby dodało ci daną funkcję do tabeli importów:

extern "C" __declspec(dllexport)
void __stdcall TabWe(DWORD)
{
  //...
}

Dodatkowo w VS2010 w kompilatorze domyślnie instalowanym (po użyciu z innego SDK już tego nie ma) jest jakiś bug, że nazwy importowanych funkcji są nadal w części dekorowane, czyli jak normalnie po użyciu extern "C" spodziewamy się że w importach nazwa będzie "TabWe", to faktycznie kompilator zostawi w importach coś ala "_TabWe@12".

1 użytkowników online, w tym zalogowanych: 0, gości: 1