WinSock, DLLe, char* i wartość NULL

0

Mam kilka pytań/problemów, na razie przedstawię tylko pierwsze.
Otóż mam własną bibliotekę dll, która niewnikając w szczegóły wyeksportowała funkcję, która pobiera PChar / char* i wysyła za pomocą WriteLn dane do hosta, z którym się wcześniej ta dllka połączyła.
Z architekturą, łączeniem itd problemów nie mam, samo wysyłanie też działa bez zarzutu. Problem pojawił się, kiedy zacząłem przesyłać inne dane niż tekst. Umiem konwertować dowolny typ danych na char*, ale tu jest tyci haczyk - w char* nie mogę zapisać wartości 0x00, choć bardzo jej potrzebuję np. w incie. Wpadłem na pomysł żeby wartość 0x00 zastępować np. 0xff, ale co wtedy z 0xff???
Ostatecznie okazuje się, że tracimy możliwość zapisania jednej z 256 możliwości. Teoretycznie jest to nic, ale uint zamiast maksymalnej wartości 2564-1 dostaje 2554-1, więc tracimy (chyba)66716671 możliwości. Czy ktoś zna jeszcze jakieś możliwości rozwiązania tego problemu??
Niestety C++ nie posiada osobnego typu byte, więc muszę tego typu dane trzymać w charach.

0
Marandil napisał(a)

Umiem konwertować dowolny typ danych na char*
(..) w char* nie mogę zapisać wartości 0x00

no to chyba tak nie do konca umiesz.. itoa()/atoi() itp?

0

Naprawdę dziwne rzeczy opowiadasz

Niestety C++ nie posiada osobnego typu byte

To sobie zrób :

typedef unsigned char byte   ;
//lub
typedef unsigned short byte ;

Przez gniazda można wysłać bajty z zakresu od 0 do 255 , i nikogo nie interesuje NULL,
to czy 0 jest liczbą czy końcem napisu zależy od interpretacji .
Należy użyć innych funkcji .

http://download.4programmers.net/socket_linux.zip

0

Marandil - widzisz, tak to juz jest ze jesli z danego zestawu znakow wybeirzesz sobie jeden znak na terminator, to defacto tracisz mozliwosc swobodnego uzywania tego znaku.. i z char:256roznych zostaje Ci char:255roznych itp i za Chiny ludowe nie upchniesz prostym podstawianiem..

sa dwie mozliwosci:

  1. banalna - przekazuj char* z dowolnymi znakami w srodku ale nie traktuj tego jako cstring tylko jako tablice znakow!! i dorob do metody drugi argument w ktorym przekazesz dlugosc tej tablicy. i voil'a, juz nie uzywamy \0 jako terminatora i wzsystko nam wolno

  2. mniej banalna - zamien kazde 0xff na sekwencje 0xff 0xff, a kazde 0x00 (oprocz terminatora) na 0xff 0xfe. w funkcji ktora to dostanie - operacja odwrotna, kazda para 0xff 0xff na jedno 0xff, kazda para 0xff 0xfe na jedno 0x00. jak znajdziesz 0xff po ktorym jest cos innego niz 0xff/0xfe - critical blad, bo to nie mozliwe jesli poprawnie zakodowane bylo. oczywiscie zamiast FF i FE mozesz uzyc dowolnych znakow, byle miec 100% pewnosc ze wsyzstko jest caly czas rozlaczne

0
klajter. napisał(a)

no to chyba tak nie do konca umiesz.. itoa()/atoi() itp?

Nie. Osobne funkcje, które np. rozbijają inta na 4 chary w/g zasady reszty z dzielenia.

Jeśli zdefiniuje osobny typ na byte, to ciągle będzie on charem, co nie?

Myślałem coś o podwójnych sekwencjach, ale zaburzają one strukturę pakietów - zamiast 4 bajtów nagłówka trzeba by pobierać więcej i sprawdzać, czy będą pasować, czy nie.

Pracuje jeszcze nad nową wersją tej biblioteki, ale ona ciągle do funkcji typu send chce argumentów typu char*.

Zaciekawiło mnie to o tej zmianie terminatorów. Wcześniej się z czymś takim nie spotkałem. Jak to uzyskać?

Z góry dziękuję za pomoc.</url>

0

Jeśli zdefiniuje osobny typ na byte, to ciągle będzie on charem, co nie?

Tak, ale nie zmienia to faktu, że jest to typ jedno bajtowy.

0

marandil - napisalem wszystko co jest potrzebne do 'przekodowania' wewnatrzstringowych \0 na cos innego.. bardziej lopatologicznie to chyba tylko kodem by sie dalo..

0

Udało mi się w końcu - ale musiałem zmienić bibliotekę. Zamiast char* używam teraz void* i inta z długością. Problem jest jednak właśnie z tą biblioteką. Otóż wcześniej była to DLLka z Delphi z INDY na pokładzie, zbudowana bez żadnych runtime packages. Teraz, aby używać void* musiałem ją napisać w C++ (Borland Turbo C++) gdzie także używam INDY, ale bez włączenia "build with runtime packages" i wskazania mu odpowiedniej biblioteki nie idzie budować.
Czy ktoś wie, jak w BTC++ skompilować program/DLLa bez "Build with Runtime Packages" z indy100.bcl (czy jakoś tak to się nazywało)?

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