jak zastąpić pole w strukturze void*

Odpowiedz Nowy wątek
2011-10-20 09:36
gość
0

Witam wszystkich,
próbuje zrobić wrappera z c++ do c# i w końcu natrafiłem na problem, otóż chce odbierać obraz video po ramkach i do tych ramek stworzona jest struktura

struct frame
{void *     buf
sizet   size
timestampt  timestamp
int bit_info}  

gdzie buf to wskaźnik do bufora, size i timestap to inne struktury które już przekonwertowałem ale z tym void* nie wiem jak sobie poradzić w c#, muszę używać unsafe?
próbowałem coś takiego,

[StructLayout(LayoutKind.Sequential)]
struct frame
{
IntPtr buf
sizet size
timestampt timestammo
int bit_info
} 

Pozostało 580 znaków

2011-10-20 12:12
Rev
0

IntPtr to dobry wybór.


Pozostało 580 znaków

2011-10-20 14:00
Gość
0

ok, zadziałało, jak teraz mogę użyć informacji zawartej buf'ie?

Pozostało 580 znaków

2011-10-20 14:11
Rev
0

Przy pomocy klasy Marshal.

http://msdn.microsoft.com/en-[...]es.marshal%28v=VS.100%29.aspx


Pozostało 580 znaków

2011-10-20 14:26
Gość
0

ok dziękuję Rev, narazie nie mam pytań :)

Pozostało 580 znaków

2011-10-22 23:56
gość
0

Witam, już mam pytanie dotyczącą odebrania kolejnej struktury, otóż mam w c++ coś takiego:

 struct foo
{
    int id;
    char[12] name;
    struct
        {
        unsigned index;
        type_t type;
        int dir;
        status status;
        union {
                struct {
                int conf_slot;
                } aud;
            struct {
                int win_in;
                int cap_dev;
                } vid;
        } stream;
        } media[MAX_SDP];
}
</code=cpp>
type_t, i status to kolejne stuktury ale z nimi sobie poradziłem i wiem że na pewno działa, z kolei mam problem z media[max_sdp]  czy dobrze zmarshalowałem i nie jestem pewien co do tego union, albo może problem tkwi w czymś innym, robie coś takiego:
```csharp
[StructLayout(LayoutKind.Sequential)]
    public struct foo
    {
        int id;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 12)]
    string name;

        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
        public mediat_[] media;

        [StructLayout(LayoutKind.Sequential)]
        public struct mediat_
        {
            public uint index;
            public typet type;
            public int dir;
            statust status;
            public streamt_ stream;
        }
        [StructLayout(LayoutKind.Explicit)]
        public struct streamt_
        {
            [FieldOffset(0)]
            public audt_ aud;
            [FieldOffset(4)]
            public vidt_ vid;
        }

        [StructLayout(LayoutKind.Sequential)]
        public struct audt_
        {
            public int conf_slot;
        }
        [StructLayout(LayoutKind.Sequential)]
        public struct vidt_
        {
            public int win_in;
            public int cap_dev;
        }  
    } 

i to powoduje że pojawia mi się taki komunikat:

System.TypeLoadException was unhandled
Message="Nie można załadować typu 'foo' z zestawu 'dllwrapper, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'."
Source="Test2"
TypeName="dllwrapper.foo"

z kolei jeśli robię coś takiego:

...
        public mediat_ media;
    ...
        [StructLayout(LayoutKind.Sequential, Size = 384)]
        public struct mediat_{
        ...
    }...
        } 

To wtedy się nie wykłada program, odczytuje wartości z tej struktury dla miedia[0] niestety interesują mnie informacje zawarte w miedia[1] ale nie mogę się tam dostać, kiedy próbowałem dodać

 [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
        public mediat_[] media;

do tej struktury także pojawiał się bład, co prawda inny niż ten wyżej ale mówiący o nieprawidłowej strukturze. Dziwi mnie też to że udało mi się odebrać strukturę która miała także stukture w strukturze typu [] i tam "poszło" od razu, więc myślę że może z tym union coś jest nie tak...
i jeszcze jedno pytanie da się zastąpić #define z c++ jakoś? i kolejne dotyczący importowania enuma jak ugryźć coś takiego?

enum  format_id { 
   FORMAT_L16 = 0, 
   FORMAT_PCM = FORMAT_L16, 
   FORMAT_PCMA = FORMAT_PACK('A', 'L', 'A', 'W'),
   FORMAT_ALAW = FORMAT_PCMA,...
}; 

gdzie

#define FORMAT_PACK(C1, C2, C3, C4) FOURCC(C1, C2, C3, C4)
#define FOURCC(C1, C2, C3, C4) ( C4<<24 | C3<<16 | C2<<8 | C1 )

uff to chyba wszystko z moich niewiadomych.

Pozostało 580 znaków

2011-10-24 10:09
gość
0

jeden problem rozwiązałem, należało

public struct foo
    {
        int id;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 12)]
        string name;

        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
        public mediat_[] media;

    }[StructLayout(LayoutKind.Sequential)]
        public struct mediat_
        {
            public uint index;
            public typet type;
            public int dir;
            statust status;
            public streamt_ stream;
        }
        [StructLayout(LayoutKind.Explicit)]
        public struct streamt_
        {
            [FieldOffset(0)]
            public audt_ aud;
            [FieldOffset(4)]
            public vidt_ vid;
        }

        [StructLayout(LayoutKind.Sequential)]
        public struct audt_
        {
            public int conf_slot;
        }
        [StructLayout(LayoutKind.Sequential)]
        public struct vidt_
        {
            public int win_in;
            public int cap_dev;
        }    

należało wywalić wewnętrzne struktury na zewnątrz i wszystko działa, pozostaje tylko enum z #define,
define zamieniłem na funkcje i generalnie chyba dobrze zamienia jednak wciąż nie wiem jak zrobić enuma z funkcją w środku...

Pozostało 580 znaków

2011-10-24 13:19
0

nie wiem jak zrobić enuma z funkcją w środku...

nie robić.

FORMAT_PCMA = 'A' <<24 | 'L' <<16 | 'A' <<8 | 'W'

czy jakoś tak. brać pod uwagę, że char w C# jest dwubajtowy, więc dla zachowania tej samej wartości co w C być może trzeba nałożyć maskę 8-bitową:

  FORMAT_PCMA = (byte)'A' <<24 | (byte)'L' <<16 | (byte)'A' <<8 | (byte)'W'

albo

  FORMAT_PCMA = ('A'&0xFF) <<24 | ('L'&0xFF) <<16 | ('A'&0xFF) <<8 | ('W'&0xFF)

Pozostało 580 znaków

2011-10-24 14:11
gość
0

ekstra ;) dziękuję za wszystkie podpowiedzi i rozwiązania, teraz już nic nie stanie mi na drodze (mam nadzieje ;P)

i tyle po mojej radości :) zastosowałem się do rozwiązania

PJMEDIA_FORMAT_PCMA = (byte)'A' << 24 | (byte)'L' << 16 | (byte)'A' << 8 | (byte)'W'

ale także spróbowałem bez (byte) a także zamiast (byte)

FORMAT_PCMA = ('A'&0xFF) <<24 | ('L'&0xFF) <<16 | ('A'&0xFF) <<8 | ('W'&0xFF)

niestety pojawił się błąd o treści:

System.TypeLoadException was unhandled
Message="Nie można załadować typu 'info_t' z zestawu 'dllwrapper, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null', ponieważ zawiera on pole obiektu o przesunięciu 8', ktre jest nieprawidłowo wyrwnane lub częściowo pokrywa się z polem niebędącym polem obiektu."
(PS cytat z VS2008, "ktre", "wywnanane")]
Generalnie mogłem coś nabroić z innymi typami ale nigdzie poza enumem format nie miałem przesunięcia, jakiś pomysł na obejście tego?

przepraszam, moja wina, tam jest wszystko ok, pomyliłem się i dałem za mały offset w pewnej strukturze która była częścią pewnej unii...
przepraszam zastanowię się dwa razy, zanim znowu zacznę pisać głupoty... za długo już nad tym siedzę
PS. enum działa także bez (byte)

Pozostało 580 znaków

2011-10-26 12:22
gość
0

Witam, ciąg dalszy problemów ze strukturami, tym razem natrafiłem na coś takiego

 struct foo
{
    bar* buf;
}
struct bar
{
    int bac;
    int kup;

}

ok, w c# zrobiłem jedna i drugą tak:

[StructLayout(LayoutKind.Sequential)]
struct foo
{
    //Marshal.PtrToStructure(buf, bar);
    IntPtr buf;
}
[StructLayout(LayoutKind.Sequential)]
struct bar
{
    int bac;
    int kup

}

i to działa, tylko jak teraz dostać się do danych z bar'a? jest coś takiego Marshal.PtrToStructure (jeszcze nie testowałem, ale to raczej to) tylko jak teraz zrobić coś takiego abym miał miał odzwierciedlenie 1:1 w strukturze (w sensie żebym mógł sobie napisać foo.bar.bac a jednocześnie mógł odbierać informacje bezpośrednio z funkcji c++)?

i jeszcze jedno pytanie bo pewnie i tak je zadam, jeszcze nie doszedłem do momentu ale widziałem w strukturze wskaźnik na inną strukturę która miała sobie wskaźniki do funkcji, jakiś pomysł?

Pozostało 580 znaków

2011-11-04 12:59
0

Witam (w końcu się zarejestrowałem), natrafiłem na dość dziwny błąd, otóż:
posiadam pewną strukturę (format) która ma w sobie unie, i ową strukturę używam w dwóch innych strukturach (video_device_info oraz video_codec_param) w ta pierwsza wygląda następująco:

 [StructLayout(LayoutKind.Sequential)]
    public video_device_info
    {
        public int id;
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)]
        public string name;
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
        public **format[]** fmt;

i ta struktura działa, natomiast w ta druga wygląda tak:

[StructLayout(LayoutKind.Sequential)]
    public struct video_codec_param
    {
        public dirt dir;
        public video_packing packing;
        public **format** enc_fmt;
        public codec_fmtp enc_fmtp;      
        public int enc_mtu;
        public **format** dec_fmt;
        public codec_fmtp dec_fmtp;
        public int ignore_fmtp;
    } 

struktura format wygląda tak:

 [StructLayout(LayoutKind.Sequential)]
    public struct format
    {
        public uint id;
        public typet type;
        public format_detail detail_type;
        public det_t det;
    }

    [StructLayout(LayoutKind.Explicit)]
    public struct det_t
    {
        [FieldOffset(0)]
        [MarshalAs(UnmanagedType.Struct)]
        public audio_t aud;
        [FieldOffset(36)]
        [MarshalAs(UnmanagedType.Struct)]
        public video_t vid;
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)]
        [FieldOffset(60)]
        public char[] user;
    }

wszystkie typy nie wymienione są albo enum'ami albo innymi strukturami które działają (odbierałem każdą po kolei i jest ok).

przechodząc do sedna
wywołując funkcję która odbiera video_device_info działa bez zarzutu,ale jeśli chce odebrać video_codec_param (obie funkcje wywołuję w identyczny sposób

 int getInfo(int id, out video_device_info vdi);

oraz int getCodecParam(int id, out video_codec_param vcp)


 ) pojawia mi się błąd
> System.Runtime.InteropServices.MarshalDirectiveException was unhandled
>   Message="Podpis typu metody nie jest zgodny z elementem PInvoke."
 napisałem sobie do testowania osobną funkcje ` typ test(){... return typ;}` którą to odbieram poszczególne elementy (na razie oprócz det_t[tej najważniejszej]) ze struktury video_codec_param i podczas odbierania struktury format dostaje ten sam błąd. Nie rozumiem czemu z video_device_info nie wyskakuję żaden błąd a video_codec_param już tak.
edytowany 2x, ostatnio: Andrewos, 2011-11-04 13:06

Pozostało 580 znaków

Odpowiedz
Liczba odpowiedzi na stronę

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