Skip to content

Work with Native C/C++ structures without declaration #2

@3F

Description

@3F

I want a more flexible using of native C/C++ complex types (like a struct), without additional declarations.
it would be nice to avoid some re-declaration of the same equivalents from C++ to C#

we can also skip some declaration if this required only inside unmanaged code, i.e.:

IntPtr codec; // we will store pointer to AVCodec struct
IntPtr context = IntPtr.Zero; // we will store pointer to AVCodecContext struct

l.bind<Action>("avcodec_register_all")();
codec   = l.bind<Func<int, IntPtr>>("avcodec_find_encoder")(AV_CODEC_ID_MP3);
context = l.bind<Func<IntPtr, IntPtr>>("avcodec_alloc_context3")(codec); // pass allocated AVCodec* to avcodec_alloc_context3
...

but if we need to work with the context above, we also should declare this type (see AVCodecContext in avcodec.h) and finally marshal it:

AVCodecContext context = (AVCodecContext)Marshal.PtrToStructure(ptr, typeof(AVCodecContext));

even if it all will be encapsulated by layer of upper level... just not so cool :)

However, we cannot provide this automatically, because final data does not have any markers of data etc.
Just byte-sequence, because the main idea it's headers, for example:

struct Spec
{
    int a;
    int b;
    Spec2* m;
};
~0x0572b018
-----------
[0]  | 0x05     <<< 4 bytes of integer type, value is 5 from a of struct Spec
[1]  | 0x00
[2]  | 0x00
[3]  | 0x00   ^
[4]  | 0x07     <<< 4 bytes of integer type, value is 7 from b of struct Spec
[5]  | 0x00
[6]  | 0x00
[7]  | 0x00   ^
[8]  | 0xd8     <<< 4 bytes of integer type, value is a pointer to struct Spec2
[9]  | 0xb1
[10] | 0x72
[11] | 0x05   ^
[12] | 0xfd
[13] | 0xfd
[14] | 0xfd
[15] | 0xfd
...

so, how about to define it automatically by size of types ? We can't detect what types are present in this sequences, but for work with complex native types, we can simply like a:

var c = get(context, int, int, long) as AVCodecContext;

c["sample_rate"]  = 44100;
c["channels"]     = 2;
c["bit_rate"]     = 64000;
...
ret = l.bind<FuncRef4<AVCodecContext, AVPacket, AVFrame, int, int>>("avcodec_encode_audio2")(c, pkt, frame, ref output);

the order-sensitive is similar for Marshal.PtrToStructure - not so good for both :)

need to think...

Metadata

Metadata

Assignees

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions