Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Closed
3F opened this issue Aug 3, 2016 · 1 comment
Closed

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

3F opened this issue Aug 3, 2016 · 1 comment
Assignees

Comments

@3F
Copy link
Owner

3F commented Aug 3, 2016

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...

@3F 3F self-assigned this Aug 3, 2016
@3F 3F added the enhancement label Aug 3, 2016
3F added a commit that referenced this issue Aug 8, 2016
…uctures without declaration #2

also:

* updated CharPtr: +BSTR, +WCharPtr
* and new UnmanagedString, that allocates strings for unmanaged code
@3F
Copy link
Owner Author

3F commented Aug 8, 2016

first experimental implementation with - 18dd9b0 ( exp_native_data branch)

NativeData
        ._(ptr)
        .t<byte>()
        .t<int, bool>(null, "flag")
        .align<long>(4);

Raw mt = NativeData
                ._(ptr)
                .align<int>(2, "a", "b")
                .t<IntPtr>("name")
                .Raw;//.CompiledFields;

dynamic z = mt.Type; //BType

int a = z.a;
int b = z.b;

string name = (CharPtr)z.name;

z.a = 5;
z.b = 7;

byte[] re = mt.Type.FieldsBinary;

-  re {byte[0x0000000c]} byte[]
        [0]    0x05    byte
        [1]    0x00    byte
        [2]    0x00    byte
        [3]    0x00    byte
        [4]    0x07    byte
        [5]    0x00    byte
        [6]    0x00    byte
        [7]    0x00    byte
        [8]    0x20    byte --
        [9]    0x78    byte   |_ pointer to allocated string 
        [10]   0xf0    byte   |
        [11]   0x56    byte --
...

and yes... now we can allocate memory for unmanaged strings, like:

using(var uns = new UnmanagedString("my managed string"))
{
    ...
    uns -> IntPtr, CharPtr, WCharPtr, BSTR
}

TODO: part of this changes I will merge in master anyway later, simply sketch

3F added a commit that referenced this issue Aug 13, 2016
…Conari:

not so bad... so it makes sense to continue improve :)

+IConfig.CacheDLR to cache dynamic types & BReader to get values from byte-sequence.

also fixed Compiler Warning (level 1) C4190
3F added a commit that referenced this issue Aug 17, 2016
    NEW: DLR features for core with caching of dynamic types.
    NEW: Added features for convenient work with Native C/C++ structures without declaration. /Issue #2
    NEW: The Mangling features by C rules: to automatically find entry points of exported functions. /Issue #3
    NEW: Added access to export functions from PE files.
         ILoader.ExportFunctionNames

    NEW: Added LSender as a simple retranslator for loggers.
    NEW: Added features for convenient work with any binary raw data.

    NEW: Added Core events:
         * BeforeUnload - Before unloading a library.
         * AfterUnload - When library has been unloaded.
         * AfterLoad - When library has been loaded.
         * PrefixChanged - When Prefix has been changed.
         * ConventionChanged - When Convention has been changed.

    FIXED: bug with CharPtr when unboxing for unmanaged code.
    FIXED: trivial fixes with implicit conversion for size_t and UIntPtr.
    CHANGED: Updated CharPtr: +BSTR, +WCharPtr & added new UnmanagedString, that allocates strings for unmanaged code.
    CHANGED: Other trivial fixes and improvements.
@3F 3F closed this as completed Nov 10, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant