Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

Problem ze zrozumiem działania funkcji tłumaczonej w VB

Ostatnio zmodyfikowano 2012-11-01 05:16
Autor Wiadomość
nowax
Temat założony przez niniejszego użytkownika
Problem ze zrozumiem działania funkcji tłumaczonej w VB
» 2012-10-29 15:21:31
Witam!
Piszę program sterujący robotem kawasaki. W tym celu używam biblioteki dll, w której utworzone zostały funkcje do użytkowania robotem. Niestety manual do biblioteki został przedstawiony na przykładach napisanych w visual basic. Większość funkcji zrozumiałem (i nawet działają w cpp), natomiast mam problem z jedną, tzw. "comand check". Chodzi dokładnie o to, że program wywołuje funkcje poczym działa bez końca, zero reakcji. Poniżej zamieszczam po kolei: wycinek kodu programu, który ja napisałem; kod z teoretycznego programu napisanego w visual basicu załączonego do manuala; opis funkcji w manualu. Byłbym naprawdę wdzięczny za wszelką okazaną pomoc.

C/C++
// wczytanie bilbioteki
HMODULE hModule = LoadLibrary( L"ASKCT.dll" );
if( hModule == NULL )
{
    cout << "Biblioteka niewczytana" << endl;
    system( "pause" );
    return 0;
}

char command[] = "SIGNAL 9";
char message[ 4092 ];

typedef long( __stdcall * pICFUNC )( long, char( & message )[ 4092 ] );
FARPROC CmdCheck = GetProcAddress( HMODULE( hModule ), "AsKCTCmdCheck" );
pICFUNC AsKCTCmdCheck;
AsKCTCmdCheck = pICFUNC( CmdCheck );

cout << "sprawdza poprawnosc zadanej komendy" << endl; //////////////////PO TEJ LINIJCE ZAWIESZA SIĘ PROGRAM!!!!!!!!!!!!!
ret_val =( AsKCTCmdCheck )( 0,( & message )[ 4092 ] );
cout << "sprawdzenie komendy:\nresult: " << ret_val << endl << endl;
system( "pause" );

Private Function ChkCmnd() As Short
Dim Mess As New VB6.FixedLengthString(4096)
Dim ret As Integer

Mess.Value = New String(Chr(0), 4096)

ret = AsKCTCmdCheck(0, Mess.Value)

If Len(TScreen.Text) > 16000 Then
TScreen.Text = ""
End If

TScreen.SelectedText = Mess.Value
ChkCmnd = ret

End Function

https://dl.dropbox.com/u/30453883/KcwinTCP-dll_page15.pdf
P-67918
crash
» 2012-11-01 05:16:24
Nie widzę całego kodu funkcji, więc tylko domniemania. Kodu nie kompilowałem, więc wiesz...

C/C++
ret_val =( AsKCTCmdCheck )( 0,( & message )[ 4092 ] );

Linijka, która uważasz, że wywala błąd.
4096 po raz pierwszy.
ret_val pobiera rezultat działania funkcji wywoływanej przez wskaźnik, funkcja ta pobiera dwa argumenty. Błąd jest w drugim parametrze: adres na 4091 bajt zmiennej message.

C/C++
typedef long( __stdcall * pICFUNC )( long, char( & message )[ 4092 ] );

//powinno być:

typedef long( __stdcall * pICFUNC )( long, char * )

Powinien być wskaźnik na tablicę char, wystarczy więc samo char* lub char[] (zobacz pierwszy parametr to sam typ long, bez nazwy zmiennej),

Idąc dalej, należy podać wskaźnik na funkcję, która ma się wykonać, funkcja musi mieć zgodne argumenty z deklaracją (long, char*). Dopiero przy wywoływaniu konkretnej funkcji przez wskaźnik należy podać argumenty, o który Ci chodzi, w tym właśnie message.

Wtedy przy wywołaniu już konkretnej funkcji, do przekazanej tablicy zostanie podstawiona jakaś konkretna, oczekiwana wartość. Wtedy i tylko wtedy - nie w typedef.

C/C++
char * message = new char[ 4096 ];

FARPROC CmdCheck = GetProcAddress( HMODULE( hModule ), "AsKCTCmdCheck" );

pICFUNC AsKCTCmdCheck;
AsKCTCmdCheck = pICFUNC( CmdCheck );

ret_val =( AsKCTCmdCheck )( 0,( & message )[ 4096 ] );
//błąd, to tak jakbyś chciał przekazać funkcji przez referencję adres 4091 bajtu //zmiennej message.

ret_val =( AsKCTCmdCheck )( 0, message ); //teraz good, wskaźnik na początek tablicy

...
delete[] message;

Obszerne wyjaśnienie działania wskaźników na funkcje.
http://www.egrafik.pl/kurs-c-plus-plus/8.3.php

//EDIT

Uproszczone wywoływanie funkcji przez wskaźnik:

C/C++
#include <string.h>
#include <iostream>

using namespace std;


long test( char * C )
{
    strcpy( C, "01234567890" );
}


int main()
{
    char message_1[ 4096 ]; //statycznie
    char * message_2 = new char[ 4096 ]; //dynamicznie
   
    typedef long( * fun_ptr )( long, char * );
   
    fun_ptr test_1 =( fun_ptr ) test( & message_1[ 0 ] ),
    test_2 =( fun_ptr ) test( message_2 );
   
   
    cout << "\nTest 1: " << message_1
    << "\nTest 2: " << message_2;
   
    delete[] message_2;
    cin.ignore();
   
    return 0;
}
P-68098
« 1 »
  Strona 1 z 1