Skip to content
New issue

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

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

Already on GitHub? # 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
# for free to join this conversation on GitHub. Already have an account? # to comment
Projects
None yet
Development

No branches or pull requests

1 participant