Code Monkey home page Code Monkey logo

cppast.codegen's People

Contributors

mirsario avatar stephenhodgson avatar wackoisgod avatar waldnercharles avatar xoofx avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

cppast.codegen's Issues

Bug: Class/Struct in a namespace is converted to member in first class scope it is used

Reproducer

    namespace ns {
        struct Foo { unsigned short _h; };
    } 
    class Bar { ns::Foo member_; };
    class Baz { ns::Foo member_; };

Issue

The struct Foo is defined as libnative.Bar.Foo instead of libnative.Foo as expected

using System;

namespace LibNative
{
    using System.Runtime.InteropServices;
    
    public static partial class libnative
    {
        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
        public partial struct Bar
        {
            public libnative.Bar.Foo member_;
            
            [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
            public partial struct Foo
            {
                public ushort _h;
            }
        }
        
        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
        public partial struct Baz
        {
            public libnative.Bar.Foo member_;
        }
    }
}

Fixed sized buffers of typedefs to primitives seem to generate incorrectly

A fixed size buffer of a typedef of a primitive generates improperly:

C

typedef uint64_t ecs_id_t;
typedef struct ecs_bulk_desc_t {
    ecs_id_t ids[32]; 
}

C#

public readonly partial struct ecs_id_t : IEquatable<ecs_id_t> { ... }
public unsafe partial struct ecs_bulk_desc_t
{
    public fixed IEquatable<ecs_id_t> ids[32];
}

The code path being hit that generates this is https://github.com/xoofx/CppAst.CodeGen/blob/master/src/CppAst.CodeGen/CSharp/Plugins/DefaultTypeConverter.cs#L177

Not sure what the correct way to resolve this is.

Struct improperly generated

This one particular struct was improperly generated using a fixed keyword and a generated type.

Result:

c++

/*! Desired configuration of the input system. */
typedef struct InputConfiguration {
  /*! Desired degrees-of-freedom mode of each controller. */
  InputControllerDof dof[Input_MaxControllers];
} InputConfiguration;

C#

/// <summary>
/// Desired configuration of the input system.
/// </summary>
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public unsafe partial struct InputConfiguration
{
    /// <summary>
    /// Desired degrees-of-freedom mode of each controller.
    /// </summary>
    public fixed libnative.InputControllerDof dof[2];
}

Error

Fixed size buffer type must be one of the following: bool, byte, short, int, long, char, sbyte, ushort, uint, ulong, float or double

Expected

I'm not really sure what the expected result here would be either besides replacing the generated type with the int equivalent value, but that doesn't seem correct.

/// <summary>
/// Desired configuration of the input system.
/// </summary>
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public unsafe partial struct InputConfiguration
{
    /// <summary>
    /// Desired degrees-of-freedom mode of each controller.
    /// </summary>
    public fixed int dof[2];
}

fails to generate enum value based on macro definition

When attempting to generate an enum using a macro definition the code generated does not compile.

Current

c++

/*! Macro to set a the prefix bytes of an API specific Result code. */
#define RESULT_PREFIX(val) (val << 16)

enum {
  /*! Defines the prefix for global Result codes. */
  ResultAPIPrefix_Global = RESULT_PREFIX(0),
};

enum {
  /*! Defines the prefix for AudioResult codes. */
  ResultAPIPrefix_Audio = RESULT_PREFIX(0x9e11)
};

C#

public enum __AnonymousCppEnum_api_3920AnonymousEnum : int
{
    /// <summary>
    /// Defines the prefix for global Result codes.
    /// </summary>
    ResultAPIPrefix_Global = unchecked((int)(0  16)enum{/*! Defines the prefix for global Result codes. */ResultAPIPrefix_Global=RESULT_PREFIX(0))),
}

public enum __AnonymousCppEnum_audio_8721AnonymousEnum : int
{
    /// <summary>
    /// Defines the prefix for AudioResult codes.
    /// </summary>
    ResultAPIPrefix_Audio = unchecked((int)(0x9e11  )), // Note this value should have also been computed using the macro.
}

Expected

public enum __AnonymousCppEnum_api_3920AnonymousEnum : int
{
    /// <summary>
    /// Defines the prefix for global Result codes.
    /// </summary>
    ResultAPIPrefix_Global = unchecked((int)0 << (int)16),
}

public enum __AnonymousCppEnum_audio_8721AnonymousEnum : int
{
    /// <summary>
    /// Defines the prefix for AudioResult codes.
    /// </summary>
    ResultAPIPrefix_Audio = unchecked((int)0x9e11 << (int)16),
}

delegate* support for function pointer type.

I have traveled the code in this repo and I want to add delegate* support.

typedef int (*fnAdd)(int,int);
struct S{
    fnAdd pfnAdd;
};

generates

struct S
{
      delegate* unmanaged[Cdelc]<int,int,int> pfnAdd;
}

I found that there is already an implementation of delegate pointers here, but it is not for function pointers, but for functions. And it doesn't seem to be used. Any tips on implementing this?

Unable to provide own implementation of DefaultFunctionConverter

I am wanting to provide my own version of this Converter but the issue here is that CppElement is internal set on CSharpElement which doesn't allow me to provide the same behavior as the default nor will it allow this to work with the mapping rules later.

Is there any specific reason this has to be internal ? Especially given the plugin architecture ?

Is this project dead?

I don't see any commits since couple of years ago. Is the code in a stable state or is it abandoned?

void typedefs generate to invalid c#

A void typedef generates to something that can't compile in C# via the default typedef converter.

typedef void ecs_poly_t; -> public readonly partial struct ecs_poly_t { public readonly void Value; ... }

I'd be happy to open a PR to fix this, but I'm not 100% sure what the correct solution is. Should the typedef just be empty if the typedef's value's type is "void"?

delegate comments are generated in the wrong location

Current:

/// <summary>
/// The summary for the cpp function delegate
/// </summary>
/// <param name="parameter1">parameter description.</param>
/// <param name="parameter2">parameter description.</param>
/// <param name="parameter3">parameter description.</param>
/// <remarks>
/// @brief This callback will be invoked whenever event is detected.
/// </remarks>
public ClassName.Callbacks.function_delegate event;

[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void function_delegate (byte parameter1, in Interop.DeviceState parameter2, IntPtr parameter3);

Expected:

/// <summary>
/// The summary for the cpp function delegate event.
/// </summary>
public ClassName.Callbacks.function_delegate event;

/// <summary>
/// The summary for the cpp function delegate.
/// </summary>
/// <param name="parameter1">parameter description.</param>
/// <param name="parameter2">parameter description.</param>
/// <param name="parameter3">parameter description.</param>
/// <remarks>
/// This callback will be invoked whenever event is detected.
/// </remarks>
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void function_delegate (byte parameter1, in Interop.DeviceState parameter2, IntPtr parameter3);

Trouble representing unions

Hi, I was having trouble getting these unions to generate correctly:

Current Result

C++

/*!
  \brief Internal structure used to simplify access of Vec3f. Do not create
  this structure directly and always use Vec3f instead.
*/
typedef struct XYZf {
  float x;
  float y;
  float z;
} XYZf;

/*! 3D vector represented with X, Y, and Z floats. */
typedef struct Vec3f {
  union {
    XYZf xyz;
    float values[3];
    struct {
      float x;
      float y;
      float z;
    };
  };
} Vec3f;

/*! Quaternion stored as X, Y, Z, W floats. */
typedef struct Quaternionf {
  union {
    /*! Values of the quaternions laid out as X, Y, Z, W. */
    float values[4];
    struct {
      float x;
      float y;
      float z;
      float w;
    };
  };
} Quaternionf;

C#

/// <summary>
/// Internal structure used to simplify access of Vec3f Do not create
/// this structure directly and always use Vec3f instead
/// </summary>
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct XYZf
{
    public float x;

    public float y;

    public float z;
}

/// <summary>
/// 3D vector represented with X, Y, and Z floats
/// </summary>
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct Vec3f
{
    [StructLayout(LayoutKind.Explicit, CharSet = CharSet.Ansi)]
    public struct Vec3funion
    {
        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
        public struct Vec3funionstruct
        {
            public float x;

            public float y;

            public float z;
        }

        [FieldOffset(0)]
        public XYZf xyz;

        [FieldOffset(0)]
        [MarshalAs(UnmanagedType.LPArray, SizeConst = 3)]
        public float[] values;
    }
}

/// <summary>
/// Quaternion stored as X, Y, Z, W floats
/// </summary>
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct Quaternionf
{
    [StructLayout(LayoutKind.Explicit, CharSet = CharSet.Ansi)]
    public struct Quaternionfunion
    {
        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
        public struct Quaternionfunionstruct
        {
            public float x;

            public float y;

            public float z;

            public float w;
        }

        /// <summary>
        /// Values of the quaternions laid out as X, Y, Z, W
        /// </summary>
        [FieldOffset(0)]
        [MarshalAs(UnmanagedType.LPArray, SizeConst = 4)]
        public float[] values;
    }
}

Expected Result

/// <summary>
/// Internal structure used to simplify access of Vec3f Do not create
/// this structure directly and always use Vec3f instead
/// </summary>
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct XYZf
{
    public float x;

    public float y;

    public float z;
}

/// <summary>
/// 3D vector represented with X, Y, and Z floats
/// </summary>
[StructLayout(LayoutKind.Explicit, CharSet = CharSet.Ansi)]
public struct Vec3f
{
    [FieldOffset(0)]
    public float x;

    [FieldOffset(4)]
    public float y;

    [FieldOffset(8)]
    public float z;

    [FieldOffset(0)]
    public XYZf xyz;

    [FieldOffset(0)]
    [MarshalAs(UnmanagedType.LPArray, SizeConst = 3)]
    public float[] values;
}

/// <summary>
/// Quaternion stored as X, Y, Z, W floats
/// </summary>
[StructLayout(LayoutKind.Explicit, CharSet = CharSet.Ansi)]
public struct Quaternionf
{
    [FieldOffset(0)]
    public float x;

    [FieldOffset(4)]
    public float y;

    [FieldOffset(8)]
    public float z;

    [FieldOffset(12)]
    public float w;

    /// <summary>
    /// Values of the quaternions laid out as X, Y, Z, W
    /// </summary>
    [FieldOffset(0)]
    [MarshalAs(UnmanagedType.LPArray, SizeConst = 4)]
    public float[] values;
}

fails to name parameters correctly when generating delegate callbacks with multiple unnamed parameters

When generating delegate callbacks with multiple unnamed parameters, the code gen will produce names with the same name.

Current:

c++

typedef void(*CallbackMethod)(Context *, Result *);

C#

[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void CallbackMethod(libnative.Context arg0, libnative.Result arg0);

Expected

[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void CallbackMethod(libnative.Context arg0, libnative.Result arg1);

Beyond binding generation...

Yeah, I know starting a title with the "Beyond" keyword is scary!

This is actually a prospective question; about the possibility, in the far future, to be able to convert C++ code to C# ... not just bindings, but the whole thing.

I don't expect it will be possible to make a full converter that works out of the box, we can only hope to have a converter that requires extensive rewriting at best... and there's two main issues that cannot be translated to c# easily: c++ templates and pointers semantics.

The c++ templating is almost impossible to handle.... and the pointers... I believe, it also was impossible to handle, until recently.

Recently I've been using Span<T> a lot, and the more I use it, the more I recall when I used to program in c++, and I've began thinking about all the code I ported from c++ to c#, how difficult it was to port due to the pointer semantics, and how easily could have been ported now by using Span<T> extensively...

So, maybe c++ to c# code conversion is not so far away? ... what do you think?

Invalid casting of enum values

When generating enums with uint values only the first value is casted to the appropriate type

Result:

C++

/*!
  \brief Fields that will be used for search operations.
  \apilevel 2
*/
typedef enum ContactsSearchField {
  /*! Search field for nickname. */
  ContactsSearchField_Name = 1u,
  /*! Search field for phone. */
  ContactsSearchField_Phone = 1u << 1u,
  /*! Search field for email. */
  ContactsSearchField_Email = 1u << 2u,
  /*! Search across all fields. */
  ContactsSearchField_All = ContactsSearchField_Name | ContactsSearchField_Phone | ContactsSearchField_Email,
 /*! Ensure enum is represented as 32 bits. */
  ContactsSearchField_Ensure32Bits = 0x7FFFFFFF
} ContactsSearchField;

C#

/// <summary>
/// 
/// </summary>
/// <remarks>
/// @brief Fields that will be used for search operations.
/// @apilevel 2
/// </remarks>
[Flags]
public enum ContactsSearchField : int
{
    /// <summary>
    /// Search field for nickname.
    /// </summary>
    ContactsSearchField_Name = unchecked((int)1u),
    
    /// <summary>
    /// Search field for phone.
    /// </summary>
    ContactsSearchField_Phone = unchecked((int)1u<<1u),
    
    /// <summary>
    /// Search field for email.
    /// </summary>
    ContactsSearchField_Email = unchecked((int)1u<<2u),
    
    /// <summary>
    /// Search across all fields.
    /// </summary>
    ContactsSearchField_All = unchecked((int)ContactsSearchField_Name | ContactsSearchField_Phone | ContactsSearchField_Email),
    
    /// <summary>
    /// Ensure enum is represented as 32 bits.
    /// </summary>
    ContactsSearchField_Ensure32Bits = unchecked((int)0x7FFFFFFF),
}

Expected:

/// <summary>
/// 
/// </summary>
/// <remarks>
/// Fields that will be used for search operations.
/// @apilevel 2
/// </remarks>
[Flags]
public enum ContactsSearchField : int
{
    /// <summary>
    /// Search field for nickname.
    /// </summary>
    ContactsSearchField_Name = unchecked((int)1u),
    
    /// <summary>
    /// Search field for phone.
    /// </summary>
    ContactsSearchField_Phone = unchecked((int)1u << (int)1u),
    
    /// <summary>
    /// Search field for email.
    /// </summary>
    ContactsSearchField_Email = unchecked((int)1u << (int)2u),
    
    /// <summary>
    /// Search across all fields.
    /// </summary>
    ContactsSearchField_All = unchecked((int)ContactsSearchField_Name | ContactsSearchField_Phone | ContactsSearchField_Email),
    
    /// <summary>
    /// Ensure enum is represented as 32 bits.
    /// </summary>
    ContactsSearchField_Ensure32Bits = unchecked((int)0x7FFFFFFF),
}

Custom type mapping

  1. I want to add custom mapping rules. eg: vec3_t => Vector3f
  2. For pointer type in C directly map to pointer type in C# too.

CheckFunction is broken

The function declaration has the following first argument:

function0(git_my_repo* myrepo

At the same time the generated code declares it as

libnative.git_my_repo myrepo

which is incorrect. The structure is passed by pointer and should have ref or out in the c# declaration. It may work on some platforms as is (i.e. Windows) but may be broken on other (i.e. Linux).

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.