Autor Wątek: DllImport, double call  (Przeczytany 696 razy)

Offline Tear

  • Użytkownik

# Kwiecień 19, 2011, 18:07:21
Mam problem przy wywolywaniu funkcji z natywnej DLL. Metoda button1_Click() wywoluje tylko raz Foo(). Czemu tak sie dzieje i jak zrobic, by oba wywolania Foo() mialy miejsce?

Kod C#:
[DllImport("DLL.dll")] public static extern void Foo();

private void button1_Click(object sender, EventArgs e)
{
    Foo();
    Foo();
}

Kod C++:
__declspec(dllexport) void __cdecl Foo()
{
MessageBox(0, TEXT("Foo"), TEXT("DLL"), MB_OK);
}


Offline Mr. Spam

  • Miłośnik przetworów mięsnych

Offline Esidar

  • Użytkownik

# Kwiecień 19, 2011, 19:22:38
spróbuj tak
__declspec(dllexport) void __cdecl Foo()
{
MessageBox(0, TEXT("Foo"), TEXT("DLL"), MB_OK | MB_SYSTEMMODAL );
}

Offline fredman7

  • Użytkownik

# Kwiecień 19, 2011, 19:53:49
Bo MessageBox to jedna z najgorszych funkcji jaka jest. Sam niestety dość boleśnie się kiedyś o tym przekonałem. Chodzi o to, że przerywa wykonanie programu w miejscu gdzie była wywołana, to oczywiście wiadomo, bo tak przecież działa funkcja, ale najgorsze jest to co dzieje się później, a mianowicie wszystkie komunikaty przychodzą do okna jakby niby nic, czyli kod, który jest pod MessageBoxem się nie wykona !!! wykona się dopiero kiedy zamkniemy MessageBoxa, a nowe komunikaty latają i są odbierane, nie trudno się domyśleć co może się stać, po za tym żeby przypadkiem nie dostać przepełnienia stosu jak przy rekurencji, kiedy kod natrafi na to samo wywołanie MessageBox, który jest aktualnie wykonywany, to ten MessageBox się nie pojawia i jest pomijany !!!!, nowy messagebox pojawi się dopiero wtedy kiedy nie ma innego MessageBoxa. Po za tym podejrzewam, że Windows Formsy nie działają na jednym wątku i to może być powodem dziwnego zachowania. Dlatego dobrym zwyczajem jest robić to co polecił Esidar, czyli zablokowanie okna rodzica, jak tego nie zrobisz możesz otrzymać nieprzyjemną niespodziankę.

Przykładowy kod w C++, klikniesz dwa razy w formę i aplikacja się wywala "Leo Why" :-)
    static int* a=0;
    static bool clicked=false;
    switch (message)
    {
        case WM_LBUTTONDOWN:
            if(clicked) (*a)++; else
            {
                clicked=true;
                MessageBox(NULL,"Exploit :-)","Hello",MB_OK);
                a=new int;
            }
            break;