DLL w delphi, odczyt w C++/wxWidgets

0

DLL - delphi/c++

mamy definicję taliby rekordów w delphi
type
RecKey = record
id : byte;
nazwa: pchar;
end;
TLstKey = array[1..10] of RecKey;

teraz taka tablica 'TLstKey' jest zwracana przez wyeksportowaną funkcję delphi

Jak odwołać się do takiej funkcji w c++,
próba deklaracji wskaźnika do 10 elementowej tablicy struktury RecKey, zdefiniowanej w c++, kończy się błędem przy ładowaniu funkcji, Jeśli zadeklaruję pamięć, aby pomieścić taką tablicę nie mam problemu, ale dane są niepoprawne - śmieci.

typedef struct Key {
unsigned char id ;
char nazwa ;
};
typedef Key
tblKey ;

//...
tblkey mkey;

    typedef void* (*pLoadKey)();
    pLoadKey LoadKey;

    LoadKey = (pLoadKey)fdll.GetSymbol("LoadKey");        

    mkey= new Key[10];
    mkey = static_cast<tblKey>(LoadKey()); 

    //dane są bzdurne
    log(wxString::Format("%i",(mkey[0]).id));
    log(wxString::Format("%s",(mkey[0]).nazwa));
0
xkpit napisał(a)
type
  RecKey = record
     id : byte;
     nazwa: pchar;
  end;

Zobacz ile wynosi sizeof(RecKey) w Delphi a ile w C++. Najprawdopodobniej Delphi alokuje na niego 8 bajtów, alignując każde pole z osobna. Można temu zapobiedz pisząc "packed record":

type
  RecKey = packed record
     id : byte;
     nazwa: pchar;
  end;
0

Hm,

Nie za bardzo wiem jak Delphi zwraca taką tablicę rekordów...
przez wartość, czy przez wskaźnik?

Deklaracja wskaźnika w C++ i przypisanie mu tego co zwraca delphi kończy się wywrotką programu przy wywołaniu funkcji z dll. Sugeruje to, że raczej nie przez wskaźnik, a jesli przez wartość, to chyba trzeba jakoś skopiować zwracaną wartość do pamięci.

0

Po pierwsze, czy masz w ogóle możliwość modyfikowania kodu delphi, czy tylko podpięcia się?

Pokaż deklarację tej funkcji w Delphi.

Gdzie jest alokacja pamięci na tę tablicę? Nie ma przypadkiem wycieku pamięci podczas takiego zwracania?

Generalnie tablice w delphi są zmiennymi przekazywanymi przez wartość - nie są "wskaźnikami na coś" jak w C++. Oczywiście możesz mieć wskaźnik na tablicę, lub niejawne przekazanie tablicy przez referencję - wtedy jest to "tablica" jako wskaźnik, na wzór C++.

0

Tylko do odczytu :-/

Deklaracja jest taka (cyt. z pierwszego posta):
type

  RecKey = record
     id : byte;
     nazwa: pchar;
  end;
  TLstKey = array[1..10] of RecKey;

z delphi zwracane jest TLstKey

w C++ alokuję (cyt. z pierwszego posta):

        mkey= new Key[10];
        mkey = static_cast<tblKey>(LoadKey());
0

Azarien prosił cię o podanie deklaracji funkcji LoadKey w delphi, a nie cytowania pierwszego posta. Przy eksportowaniu funkcji/metod zawsze jawnie określaj konwencję wywołania, np. __stdcall. Po obu stronach, czyli w delphi i C, musi być taka sama.

mkey= new Key[10];
mkey = static_cast<tblKey>(LoadKey());

Nie wiem po co alokujesz pamięć, jeśli w następnej linii, przypisaniem, gubisz ją - masz wyciek.

0

Z Delphi zwracane jest TLstKey, czyli array[1..10] of RecKey
W C++ natomiast odbierasz tblKey, czyli Key*
Pierwsze jest tablicą, drugie jest wskaźnikiem.
TABLICE W DELPHI NIE SĄ WSKAŹNIKAMI.
sizeof(tblKey) zwraca 4 – rozmiar wskaźnika. sizeof(TLstKey) zwróci 80 – rozmiar 10-elementowej tablicy.

0

Z Delphi zwracane jest TLstKey, czyli array[1..10] of RecKey
W C++ natomiast odbierasz tblKey, czyli Key*
Pierwsze jest tablicą, drugie jest wskaźnikiem.
TABLICE W DELPHI NIE SĄ WSKAŹNIKAMI.
sizeof(tblKey) zwraca 4 – rozmiar wskaźnika. sizeof(TLstKey) zwróci 80 – rozmiar 10-elementowej tablicy.

Deklaruję pamięć dla 10 elementów Key (1+4)*10

skoro nie są wskaźnikami, to istnieje jakiś sposób aby się dobrać do tego co jest zwracane przez delphi, jak

0

Wiesz co? Weź mi napisz minimalny program używający tego - dllka z jedną funkcją zwracającą to + program (nawet konsolowy, oczywiście w Delphi) wywołujący funkcję, obejrzę jak to jest zrealizowane na niskim poziomie.

0

to z pierwszego posta nie wystarczy?

0

'kropek' wydaje mi się, pytał o zamieszczenie BINAREK, które mógłby wybebeszyć i sprawdzwić jak faktycznie Delphi to zwraca

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