Navigacija
Lista poslednjih: 16, 32, 64, 128 poruka.

DllImport, Marshal problem

[es] :: .NET :: DllImport, Marshal problem

[ Pregleda: 2360 | Odgovora: 8 ] > FB > Twit

Postavi temu Odgovori

Autor

Pretraga teme: Traži
Markiranje Štampanje RSS

erkan
Sarajevo

Član broj: 12339
Poruke: 267
*.bstelecom.ba.

ICQ: 238530669


Profil

icon DllImport, Marshal problem27.01.2006. u 08:56 - pre 222 meseci
Pozdrav svima,
imam problem sa dll-om napisanim u C-u. Sigurno vec pogadjate, radi se tipovima
parametara koji se prosljedjuju funkcijama dll-a a ne odgovaraju tipovima u C#-u.

Izvinjavam se na duzini posta jer ima puno koda, zaista mi je bitno da skontam
rjesenje pa cu se potruditi da stavim sto je moguce manje koda a da , opet, bude jasno

Problem je sljedeci:

dio koda iz dll-s je:

Code:
// C kod 

struct iaxc_ev_levels {
    float input;
    float output;
};

struct iaxc_ev_text {
    int type;
    int callNo; /* call number for IAX text */
    char cause;
    char message[IAXC_EVENT_BUFSIZ];
};

struct iaxc_ev_call_state {
    int callNo;
    int state;
    int format;
    char remote[IAXC_EVENT_BUFSIZ];
    char remote_name[IAXC_EVENT_BUFSIZ];
    char local[IAXC_EVENT_BUFSIZ];
    char local_context[IAXC_EVENT_BUFSIZ];
};

struct iaxc_netstat {
        int jitter;
        int losspct;
        int losscnt;
        int packets;
        int delay;
        int dropped;
        int ooo;
};

struct iaxc_ev_netstats {
    int callNo;
    int rtt;
    struct iaxc_netstat local;
    struct iaxc_netstat remote;
};

struct iaxc_ev_url {
    int callNo;
    int type;
    char url[IAXC_EVENT_BUFSIZ];
};

struct iaxc_ev_video {
    int callNo;
    int format;
    int width;
    int height;
    unsigned char *data;
};

struct iaxc_ev_registration {
    int id;
    int reply;
    int msgcount;
};

typedef struct iaxc_event_struct {
    struct iaxc_event_struct *next;
    int type;
    union {
        struct iaxc_ev_levels         levels;
        struct iaxc_ev_text         text;
        struct iaxc_ev_call_state     call;
        struct iaxc_ev_netstats     netstats;
        struct iaxc_ev_url          url;
        struct iaxc_ev_video        video;
        struct iaxc_ev_registration reg;
    } ev;
} iaxc_event;

typedef int (*iaxc_event_callback_t)(iaxc_event e);
EXPORT void iaxc_set_event_callback(iaxc_event_callback_t func);


Posebno treb aobratiti paznju na definisani tip iaxc_event i tip
iaxc_event_callback_t kao pointer na funkciju


Kako bih ovaj dll mogao koristiti u C#-u, odradio sam sljedecu stvar:

Code:


// sve strukture sam odradio sa:[StructLayout(LayoutKind.Sequential)] 
// pa necu ovdje pisati da ne dupliram kod...

// ... i ono sto je problematicno ...

                StructLayout(LayoutKind.Sequential)]
        public class iaxc_event // originalno, ovo je bila struktura
        {
            public iaxc_event next; // originalno (u C-u) je bio pointr na strukturu
                public int                              type;                
                public iaxc_ev_levels             levels;
                public iaxc_ev_text             text;
                public iaxc_ev_call_state          call;
                public iaxc_ev_netstats            netstats;
                public iaxc_ev_url                    url;
                public iaxc_ev_video            video;
                public iaxc_ev_registration        reg;
                
        };

                // a zatim i definisao i delegat koji bi se koristio umjesto pointera na funkciju:

                public delegate int my(iaxc_event evnt);
                my myDelegate = null;
               
               // 'importovao' dll funkcije, a izmedju ostalih i ova:
               [DllImport(".\\extern\\iaxclient.dll")]
               public static extern void iaxc_set_event_callback(my delegat);

               // u konstruktoru ove klase stoji:
                   
       public CIAXClient()
        {
                        myDelegate = new my(iaxc_callback);
            this.OnError = new error(ErrorOccurred);
            this.OnChanged = new info(InfoMessage);
            try
            {
                iaxc_initialize(AUDIO_INTERNAL, 3);
                iaxc_set_silence_threshold(SILENCE_TRESHOLD);
                                
                                // BITNA dll f-ja.... proslijedi se delegat DLL f-ji i prodje bez problema
                iaxc_set_event_callback(myDelegate);
                // ovdje izbacuje izuzetak
                if(iaxc_start_processing_thread() == -1)
                    Error("greska...thread");
            }
            catch(Exception ex)
            {
                Error(ex.Message);
            }
            
        }
                
                 // f-ja dodjeljena delegatu:
                 

       int iaxc_callback(iaxc_event e)
        {
                       // PROBLEM !!!!!
                       // parametar 'e' je NULL
            if(e == null)
            {
                Error("reference null");
                return 1;
            }

            switch(e.type) 
            {
                case IAXC_EVENT_LEVELS:
                    return levels_callback(e.levels.input, e.levels.output);
                case IAXC_EVENT_TEXT:
                    return status_callback(new string(e.text.message));
                case IAXC_EVENT_STATE:
                    return HandleStateEvent(e.call);
                    
                default:
                    return 0;  // not handled
            }
        }



Dakle, problem se javlja u konstruktoru kada se pozove dll f-ja
Code:

iaxc_start_processing_thread() 


a u tom tredu se poziva f-ja koja pripada delegatu, tj. f-ja
Code:
 iaxc_callback

odnosno, parametar e je uvijek NULL, sto vjerovatno upucuje na cinjenicu
da nisam dobro uradio 'marshalizaciju' strukture:

Code:

typedef struct iaxc_event_struct {
    struct iaxc_event_struct *next;
    int type;
    union {
        struct iaxc_ev_levels         levels;
        struct iaxc_ev_text         text;
        struct iaxc_ev_call_state     call;
        struct iaxc_ev_netstats     netstats;
        struct iaxc_ev_url          url;
        struct iaxc_ev_video        video;
        struct iaxc_ev_registration reg;
    } ev;
} iaxc_event;



Moze li neko pomoci


[Ovu poruku je menjao erkan dana 27.01.2006. u 09:57 GMT+1]
Samo se budala saplice na kamen iza sebe.
 
Odgovor na temu

erkan
Sarajevo

Član broj: 12339
Poruke: 267
*.bstelecom.ba.

ICQ: 238530669


Profil

icon Re: DllImport, Marshal problem27.01.2006. u 14:18 - pre 222 meseci
Pokusao sam i da kreiram 'UNIJU' u C#-u, na sljedeci nacin
ali javlja gresku da ne prepoznaje takav tip, znaci, iskompajlira sve fino
i pokrene aplikaciju ali javi gresku.

Code:


// ANALOGNU UNION-u u C-u
[StructLayout(LayoutKind.Explicit)]
        public struct evnt
        {
            [FieldOffset(0)]
            public iaxc_ev_levels          levels;
            [FieldOffset(0)]
            public iaxc_ev_text          text;
            [FieldOffset(0)]    
            public iaxc_ev_call_state      call;
            [FieldOffset(0)]    
            public iaxc_ev_netstats      netstats;
            [FieldOffset(0)]    
            public iaxc_ev_url           url;
            [FieldOffset(0)]
            public iaxc_ev_video         video;
            [FieldOffset(0)]    
            public iaxc_ev_registration  reg;
        };
        
        
        [StructLayout(LayoutKind.Sequential)]
        public class iaxc_event // originalno, ovo je bila struktura
        {
                // [MarshalAs(UnmanagedType.LPStruct)]
                public iaxc_event next; // originalno (u C-u) je bio pointr na strukturu
                public int type;                
                public evnt ev;        
        };


Dakle, i dalje nista.
pomooooc :)
.


Samo se budala saplice na kamen iza sebe.
 
Odgovor na temu

NrmMyth
Ivan Maček
Split

Član broj: 63456
Poruke: 849
*.cmu.carnet.hr.

Sajt: www.dump.hr


Profil

icon Re: DllImport, Marshal problem28.01.2006. u 22:11 - pre 222 meseci
Evo ti nesto na temu.
 
Odgovor na temu

erkan
Sarajevo

Član broj: 12339
Poruke: 267
*.bstelecom.ba.

ICQ: 238530669


Profil

icon Re: DllImport, Marshal problem30.01.2006. u 13:01 - pre 221 meseci
Link je dobar hvala ti,

postavio sam
Code:

    [StructLayout(LayoutKind.Explicit)]
        public struct evnt
        {
            [FieldOffset(0)]
            public iaxc_ev_levels          levels;
            [FieldOffset(0)]
            public iaxc_ev_text          text;
            [FieldOffset(0)]    
            public iaxc_ev_call_state      call;
            [FieldOffset(0)]    
            public iaxc_ev_netstats      netstats;
            [FieldOffset(0)]    
            public iaxc_ev_url           url;
            [FieldOffset(0)]
            public iaxc_ev_video         video;
            [FieldOffset(0)]    
            public iaxc_ev_registration  reg;
        }


dakle, definisao kao uniju ali javlja gresku:
Code:

Could not load type evnt...
...
because it contains an object field at offset 0 has incorrectly aligned
or overlapped by a non-object field.


nije mi jasno..

Samo se budala saplice na kamen iza sebe.
 
Odgovor na temu

NrmMyth
Ivan Maček
Split

Član broj: 63456
Poruke: 849
*.cmu.carnet.hr.

Sajt: www.dump.hr


Profil

icon Re: DllImport, Marshal problem31.01.2006. u 09:38 - pre 221 meseci
FieldOffset() ti (koliko se sijecam) postavlja poziciju u strukturi. Pa ne mogu ti svi clanovi biti jedan preko drugoga naslagani. Moras navesti ofset u bajtovima, koliko je svaki member pomaknut od pocetka strukture.
 
Odgovor na temu

erkan
Sarajevo

Član broj: 12339
Poruke: 267
*.bstelecom.ba.

ICQ: 238530669


Profil

icon Re: DllImport, Marshal problem31.01.2006. u 09:58 - pre 221 meseci
Mogu biti 'naslagani' ako se radi o uniji
To i jeste poenta unije.
Ali ja i dalje ne razumijem zasto javlja gresku. Ovako stoji u svim
mogucim tutorialima koje sam nasao na ovu temu, barem sam ja tako shvatio :).
Problem bi se javio ako su clanovi unije referencni tipovi, ali nisu jer
se radi o strukturama.
Mada i ako skontam (nekad) rjesenje za poravnanje za koje javlja gresku, ostaje
mi problem da struktura sadrzi pointer na strukturu svog tipa (kako je izvorno u C kodu).
Toga u C#-u nema, tako da bi mogao pokusati sa referencom na objekat
ili slicno. Kakogod, da pokusam rijesiti jedno po jedno. Prvo da rijesim problem poravnanja.

Zar je moguce da niko nije dosad nailazio na ovakav problem?!

[Ovu poruku je menjao erkan dana 31.01.2006. u 11:21 GMT+1]
Samo se budala saplice na kamen iza sebe.
 
Odgovor na temu

NrmMyth
Ivan Maček
Split

Član broj: 63456
Poruke: 849
*.cmu.carnet.hr.

Sajt: www.dump.hr


Profil

icon Re: DllImport, Marshal problem02.02.2006. u 08:02 - pre 221 meseci
Posto ti nitko ovdje ne moze pomoci. Potrazi fnformacije ovdje.
http://www.forum.hr/showthread.php?t=124495
Ako ne nadjes nista upitaj na tom threadu.
 
Odgovor na temu

erkan
Sarajevo

Član broj: 12339
Poruke: 267
*.bstelecom.ba.

ICQ: 238530669


Profil

icon Re: DllImport, Marshal problem02.02.2006. u 13:54 - pre 221 meseci
eh, proradilo je onda kada sam ukinuo (zakomentarisao) sve elemente u
strukturama koje su referentnog tipa.
Znaci proradilo, nema exception-a, medjutim, svejedno, ne mogu dalje bez tih
zakomentarisanih varijabli trebace mi dalje u kodu.
Ipak, i to je neki trag.

Citat:
MSDN: "In managed code, value types and reference types are not
permitted to overlap."


Znaci ili jedno ili drugo.
Razmisljam o tome da umjesto strukture proslijedim strukturu koja bi sadrzala
samo niz bajta koji bi odgovarao velicini strukture a onda u kodu izdvajao
( iz tog niza ) varijable pojedinacno.

Ima li iko kakav komentar?
Nemoguce da niko nije imao ovakvih problema ljudi!!?

:-o

[Ovu poruku je menjao erkan dana 02.02.2006. u 14:59 GMT+1]
Samo se budala saplice na kamen iza sebe.
 
Odgovor na temu

erkan
Sarajevo

Član broj: 12339
Poruke: 267
*.bstelecom.ba.

ICQ: 238530669


Profil

icon Re: DllImport, Marshal problem03.02.2006. u 08:22 - pre 221 meseci
Evo rjesenja (nadam se :)):

Code:

[StructLayout(LayoutKind.Explicit)]
        public struct iaxc_event 
        {
            [FieldOffset(0)]
            IntPtr next;        // umjesto pointera na strukturu
            [FieldOffset(4)]
            public int type;             
            [FieldOffset(8)]
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = /*n=*/2060)]    // n-duzina najduze strukture
            public byte[] evt;       // umjesto: public evnt evt;
        };


Eto, zasad radi neke osnovne stvari a kasnije cemo vidjet... ima toga puno ...
Znaci, iz zadnjeg clana se parsira rjesenje (dakle, nema uniona...)
Samo se budala saplice na kamen iza sebe.
 
Odgovor na temu

[es] :: .NET :: DllImport, Marshal problem

[ Pregleda: 2360 | Odgovora: 8 ] > FB > Twit

Postavi temu Odgovori

Navigacija
Lista poslednjih: 16, 32, 64, 128 poruka.