[C#] nietypowy problem Wskaźniki

0

Witam!

Pisząc program oparty o SDK napisane w C natrafiłem na problem otóż jedna z funkcji przyjmuje jako parametr wskaźnik typu short[short*] natomiast z opisu wynika że należy w to miejsce wstawić wskaźnik na strukturę.

Udostępniam oczywiście całą dokumentację, bibliotekę w wersjach: stsdcall oraz cdecl, plik nagłówkowy
Problem tyczy się funkcji SCL_ShowString[Linia 122 SCl_API_DLL.h]. W dokumentacji jest to rozdział 5.10 z refenrencją do rozdziałów 9.2[tu jest opis struktury] oraz 9.3.
Sama struktura nazywa się TextOutInfo. Typ BOOL w źródłach jest to 4 bajtowa liczba bez znaku[0-false]

Próbowałem to rozwiązać na kilka sposobów ostatnie rozwiązanie(nie działające):

Uint16 id = 0;
//ładowanie funkcji
        [DllImport("SCL_API_stdcall.dll", CharSet = CharSet.Unicode)]
        static extern uint SCL_Close(UInt16 DevID);

        [DllImport("SCL_API_stdcall.dll", CharSet = CharSet.Unicode)]
        static extern uint SCL_ComInitial(UInt16 DevID, int ComPort, int Boudrate, int LedNum,
                                    int TimeOut, int retry, bool SCL2008);

        [DllImport("SCL_API_stdcall.dll", CharSet = CharSet.Unicode)]
        static extern unsafe uint SCL_ShowString(UInt16 DevID, short *info, string text);
//[...]
uint success = 0;
            string ip = RemoveSpaces(textBox1.Text);
            success = SCL_ComInitial(id, 7, 57600, 0, 2, 4, true);
            TextOutInfo* info; 
            info->Left = 2;
            info->Top = 2;
            info->Height = 10;
            info->Width = 50;
            info->XPos = 0;
            info->YPos = 0;
            info->ASCFont = 1;
            info->HZFont = 1;       
       
            success = SCL_ShowString(id, info, "test");
             //Pominąłem sprawdzanie zadziałania funkcji(success > 0)
             SCL_Close(id);
        }

Z góry dziękuję i jeśli to możliwe proszę o szybką odpowiedź.
Pozdrawiam Bartek

-------edit--------
Zapomniałem dodać że SDK służy do obsługi telebimu

0

Stworzyles wskaznik, ale nie zarezerwowales pamieci pod niego. Tu masz przyklad rezerwacji pamieci pod strukture http://msdn.microsoft.com/en-us/library/4ca6d5z7.aspx.

Czyli cos w stylu:

static extern unsafe uint SCL_ShowString(UInt16 DevID, IntPtr info, string text);
...
IntPtr ptr = Marshal.AllocHGlobal(Marshal.SizeOf(TextOutInfo));
Marshal.StructureToPtr(new TextOutInfo(){Param1 = ..., Param2 = ...}, ptr, false);
SCL_ShowString(id, ptr, "test");
0

Dzięki!

Nigdy nie używałem wskaźników w c# ;-)

Pozdrawiam Bartek

1

I nie używaj ;)

Ja też nigdy nie używałem, ale coś mi się tłucze w głowie że powinieneś użyć (dodatkowo) słówka kluczowego fixed { } - a to dlatego że GC w C# robi z pamięcią procesu co tylko zapragnie, i o ile z referencjami to nie stanowi problemu, to jeśli GC zdecyduje się ci odpalić odśmiecanie podczas kiedy używasz wskaźnika to może się okazać że wskaźnik już na nic konkretnego nie wskazuje (struktura się przesunęła na inne miejsce a wskaźnik pozostał taki sam).

pozdrawiam.

0

Jesli zarezerwuje pamiec za pomoca klasy Marshall, to tak sie nie stanie, ta klasa to gwarantuje.

0
MSM napisał(a)

I nie używaj ;)
Łatwo powiedzieć, gdy wywołujesz zewnętrzną bibliotekę, która wskaźnik przyjmuje, albo zwraca.
Poza tym, w samym C# użycie wskaźników często daje znaczne przyspieszenie kodu, np. w operacjach na bitmapach.

1

Co do operacji na bitmapach widziałem bardzo sprytny artykuł nt. bitmapy o bezpośrednim dostępie do pikseli w C# - szybka i bez unsafe.

Zresztą... Wiem że czasami wskaźnik jest konieczny, ale jest jakby "ostatecznością". (zresztą jeśli się da to lepiej korzystać z IntPtr -a niż bezpośrednich wskaźników)

0
MSM napisał(a)

Co do operacji na bitmapach widziałem bardzo sprytny artykuł nt. bitmapy o bezpośrednim dostępie do pikseli w C# - szybka i bez unsafe.
Jestem ciekaw, bo eksperymentowałem na różne sposoby, a wskaźniki i tak były najszybsze.

1

Hmm, nie przeprowadzałem testów szybkości, ale odwoływanie się do pól tablicy za wiele czasu nie może zabierać.

http://revo.pl/index.php/blog/detailed/38

0

Dzięki za zainteresowanie.
A co do używania wskaźników to zawsze omijałem je szerokim łukiem, ponieważ uważam że tak wysoce rozwinięty i obiektowy język programowania jakim jest c# nie potrzebuje wskaźników.

Pozdrawiam Bartek

0
grabie2 napisał(a)

A co do używania wskaźników to zawsze omijałem je szerokim łukiem, ponieważ uważam że tak wysoce rozwinięty i obiektowy język programowania jakim jest c# nie potrzebuje wskaźników

Zabrzmialo jakbys pracowal w Microsofcie... :P

0
grabie2 napisał(a)

tak wysoce rozwinięty i obiektowy język programowania jakim jest c# nie potrzebuje wskaźników.
Chciałoby się. Przeczytaj wątek jeszcze raz. Można ich używać wprost (np. byte*), można na bardzo okrężny sposób (różne GCHandle, IntPtr) ale czasem po prostu... potrzeba.

0

Przeczytałem dokładnie i wiem że wskaźników można używać na wiele sposobów. Jednak mi nie zdarzyło się korzystać z biblioteki wymagającej innego wskaźnika jak char* ;-)

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