Adres funkcji

0

Witam.

Czy istnieje w C# jakakolwiek możliwość uzyskania adresu funkcji i zapisania go do stringa??

Z góry dziękuję.

0

Chodzi mi o adres funkcji a zmiennej.

0

A po co zapisywac do stringa? Delegat Ci nie wystarczy?

0

Jeśli zachciewa ci się adresu funkcji pod C#, to znaczy że robisz coś źle, nie rozumiejąc idei kodu zarządzalnego.

0

Na 99,9% wystarczy ci delegata, ale skoro tak bardzo chcesz:

string adres = Type.GetType("namespace.klasa").GetMethod("metoda", BindingFlags.NonPublic | BindingFlags.Instance
    | BindingFlags.Static).MethodHandle.GetFunctionPointer().ToString();
0

Sprawa wygląda tak: z poziomu C# obsługuje bibliotekę Delphi posiadającą jedna jedyną metodę:

/* Command(LnId : TLnId; InpStr: string; var OutBufPtr :pchar; var ErrBufPtr : pchar):TStatus; stdcall; */

        [DllImport("RZ40Dev.dll", CharSet = CharSet.Unicode, EntryPoint = "Command")]
        public static extern int Command(int LnId, [MarshalAs(UnmanagedType.LPArray)] byte[] InpStr,ref string OutBufPtr, ref string ErrBufPtr); 

Załączam również jej zmapowanie w C#. Problem polega na tym że przez parametr InpStr przekazuje się do biblioteki różne instrukcje, w tym jedą która alokuje pamięć. Problem w tym że funkcja ta jako parametr InpStr w tym przypadku nie przyjmuje adresu funkcji alokującej pamięć lecz stringa w postaci 'Instrukcja_alokuj_pamiec=adres_funkcji_alokujacej_pamiec'. Dlatego właśnie potrzebuje adres funkcji a nie mogę sprawy załatwić delegatami. Pytanie tylko jak to wszystko okielznac z poziomu C#, tzn napisac funkcje alokujac okreslona ilosc bajtow i zwracajaca adres do tej tablicy a adres do tej funkcji przekazac do dll.

Stąd moje kolejne pytanie: Czy mozliwe jest wywolanie funkcji alokujacej pamiec w kodzie zarzadzalnym z poziomu kodu niezarzadzalnego oraz jak taka funkcja powinna wygladac??

0

O rany boskie!
Kto pisał tę bibliotekę? Nie dość, że przyjmuje adres funkcji (domyślam się że chodzi tu o callback) w stringu w postaci jakiegoś quasi-polecenia (WTF!) to jeszcze jest to delphiowy string, który raz że może oznaczać zupełnie innego stringa w różnych wersjach Delphi, to dwa że jest to typ dynamicznie zarządzany przez delphiowy memory manager. Powodzenia w opanowaniu tego z poziomu C# tak, by się nie sypało…
Biblioteka wyraźnie pisana jest pod Delphi, twórca nie przewidział (albo się nie znał) że ktoś będzie się do niej dobierał spod innego języka.
Jeśli nie zapanujesz nad tym pod C#, może będziesz musiał napisać drugą bibliotekę - pomostową, w Delphi, a być może w C++/CLI.

0

Ja nie pisałem tej biblioteki:). Ale ok udało mi się połączyć z nią w C#. wygląda to tak:

  • w C# funkcja wygląda tak:

private static extern int CommandBase(int LnId, [MarshalAs(UnmanagedType.LPArray)] byte[] InpStr, [MarshalAs(UnmanagedType.AnsiBStr)] out string OutBufPtr, [MarshalAs(UnmanagedType.AnsiBStr)] out string ErrBufPtr);

-alokacja pamięci wygląda tak, oraz pobranie adresu funkcji:

private static System.IntPtr[] AllocAdr = new System.IntPtr[2];             //tablica 2-elementowa zawierajaca adresy przydzielonych obszarów pamieci
                                                                                    //po każdym użyciu  funkcji Command należy bezwzględnie wywołać funkcję FreeMem();
        /* Funkcja Alokująca pamięć */
        static public System.IntPtr GetMem(int Size)
        {
            if (AllocAdr[0] == System.IntPtr.Zero)
            {
                AllocAdr[0] = Marshal.AllocHGlobal(Size);
                return AllocAdr[0];
            }
            else
            {
                AllocAdr[1] = Marshal.AllocHGlobal(Size);
                return AllocAdr[1];
            }
        }

        
        private delegate System.IntPtr OnGetMemFuncDel(int Size);
        static OnGetMemFuncDel d = new OnGetMemFuncDel(GetMem);
        static System.IntPtr funcPtr = Marshal.GetFunctionPointerForDelegate(d);
        static public Int32 funcAddressInt = (int)funcPtr;                         //adres funkcji alokującej pamięć (int)
        static public string funcAddressStr = funcAddressInt.ToString();           //adres funkcji alokującej pamięć (int)

Pojawia się znowu inny problem, mianowicie funkcja command nie jest nigdzie opisana i nie do końca znam parametry przekazywane do dll-i poprzez InpStr, ale tutaj już nikt mi nie pomoże. Pozdrawiam. PS. Jeżeli kody przedstawione powyżej nie są do końca poprawne to proszę o komentarz:)

0

akurat masz farta, ze jest UnmanagedType.AnsiBStr, ktore jest zgodne z Delphiowym AnsiString (defaultowy string do czasu wprowadzenia Unicode) :)

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