Error in structure array with variable length

Open
#1,382 9 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Assessment

Difficulty
4/5
Estimated time
3-5 days
Newbie friendliness
32/100
Issue type
Bug
Clarity
Mostly clear
Activity status
Stale
Tech stack
c, csharp
Domain
devtools, tooling

Research direction

Start with sd_rpc.h and the generated NrfBleDriver.cs around AttrInfo16 and AttrInfo128, then inspect how Preprocess and Postprocess receive the AST. Reproduce the shown C# compiler errors for the variable-length array union. Done means the generated C# compiles for these structures without the invalid fixed-statement and indexing expressions.

Written by the indexing model from the issue text.

Description

Hello,

Brief Description

I'm trying to generate a binding for the library nrf-ble-driver-4.1.1-win_x86_64, which can be donwload from https://github.com/NordicSemiconductor/pc-ble-driver/releases. The project is open source and I'm using the release build (.h and dll) for Windows x86 64bits. The wrapper will be included in a C# project.

Used headers

I'm using only the header sd_rpc.h. This have other headers inside.

Used settings

The configuration is as below:

        public void Postprocess(Driver driver, ASTContext ctx)
        {
        }

        public void Preprocess(Driver driver, ASTContext ctx)
        {
        }

        public void Setup(Driver driver)
        {
            driver.Options.GeneratorKind = GeneratorKind.CSharp;
            driver.Options.GenerateDefaultValuesForArguments = true;
            var module = driver.Options.AddModule("NrfBleDriver");
            module.OutputNamespace = "NrfBleDriver";
            module.LibraryName = "NrfBleDriver";
            module.IncludeDirs.Add(@"..\..\nrf-ble-driver-4.1.1-win_x86_64\include\sd_api_v6");
            module.Headers.Add("sd_rpc.h");
            module.LibraryDirs.Add(@"..\..\nrf-ble-driver-4.1.1-win_x86_64\lib");
            module.Libraries.Add("nrf-ble-driver-sd_api_v6-mt-4_1_1.lib");
        }

        public void SetupPasses(Driver driver)
        {
        }
Stack trace or incompilable generated code

The file NrfBleDriver.ce is generated without issues. However, at the moment of building the C# project, the following errors appears:

1>C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\MSBuild\Current\Bin\Microsoft.Common.CurrentVersion.targets(2081,5): warning MSB3270: There was a mismatch between the processor architecture of the project being built "MSIL" and the processor architecture of the reference "DIR_REMOVED\nrf-ble-driver\bin\Debug\nrf-ble-driver.exe", "AMD64". This mismatch may cause runtime failures. Please consider changing the targeted processor architecture of your project through the Configuration Manager so as to align the processor architectures between your project and references, or take a dependency on references with a processor architecture that matches the targeted processor architecture of your project.
1>DIR_REMOVED\NrfBleDriverTest\NrfBleDriver.cs(14991,69,14991,102): error CS0209: The type of a local declared in a fixed statement must be a pointer type
1>DIR_REMOVED\NrfBleDriverTest\NrfBleDriver.cs(14998,162,14998,235): error CS0021: Cannot apply indexing with [] to an expression of type 'BleGattcAttrInfo16T'
1>DIR_REMOVED\NrfBleDriverTest\NrfBleDriver.cs(15006,69,15006,102): error CS0209: The type of a local declared in a fixed statement must be a pointer type
1>DIR_REMOVED\NrfBleDriverTest\NrfBleDriver.cs(15013,90,15013,163): error CS0021: Cannot apply indexing with [] to an expression of type 'BleGattcAttrInfo16T'
1>DIR_REMOVED\NrfBleDriverTest\NrfBleDriver.cs(15023,70,15023,104): error CS0209: The type of a local declared in a fixed statement must be a pointer type
1>DIR_REMOVED\NrfBleDriverTest\NrfBleDriver.cs(15030,164,15030,238): error CS0021: Cannot apply indexing with [] to an expression of type 'BleGattcAttrInfo128T'
1>DIR_REMOVED\NrfBleDriverTest\NrfBleDriver.cs(15038,70,15038,104): error CS0209: The type of a local declared in a fixed statement must be a pointer type
1>DIR_REMOVED\NrfBleDriverTest\NrfBleDriver.cs(15045,91,15045,165): error CS0021: Cannot apply indexing with [] to an expression of type 'BleGattcAttrInfo128T'

The part of the code showing the errors are:

            public global::NrfBleDriver.BleGattcAttrInfo16T[] AttrInfo16
            {
                get
                {
                    fixed (global::NrfBleDriver.BleGattcAttrInfo16T __arrPtr = __instance.attr_info16)
                    {
                        global::NrfBleDriver.BleGattcAttrInfo16T[] __value = null;
                        if (__arrPtr != null)
                        {
                            __value = new global::NrfBleDriver.BleGattcAttrInfo16T[1];
                            for (int i = 0; i < 1; i++)
                                __value[i] = global::NrfBleDriver.BleGattcAttrInfo16T.__CreateInstance(*((global::NrfBleDriver.BleGattcAttrInfo16T.__Internal*)&(__arrPtr[i * sizeof(global::NrfBleDriver.BleGattcAttrInfo16T.__Internal)])));
                        }
                        return __value;
                    }
                }

                set
                {
                    fixed (global::NrfBleDriver.BleGattcAttrInfo16T __arrPtr = __instance.attr_info16)
                    {
                        if (value != null)
                        {
                            if (value.Length != 1)
                                throw new ArgumentOutOfRangeException("value", "The dimensions of the provided array don't match the required size.");
                            for (int i = 0; i < 1; i++)
                                *(global::NrfBleDriver.BleGattcAttrInfo16T.__Internal*) &__arrPtr[i * sizeof(global::NrfBleDriver.BleGattcAttrInfo16T.__Internal)] = *(global::NrfBleDriver.BleGattcAttrInfo16T.__Internal*)value[i].__Instance;
                        }
                    }
                }
            }

            public global::NrfBleDriver.BleGattcAttrInfo128T[] AttrInfo128
            {
                get
                {
                    fixed (global::NrfBleDriver.BleGattcAttrInfo128T __arrPtr = __instance.attr_info128)
                    {
                        global::NrfBleDriver.BleGattcAttrInfo128T[] __value = null;
                        if (__arrPtr != null)
                        {
                            __value = new global::NrfBleDriver.BleGattcAttrInfo128T[1];
                            for (int i = 0; i < 1; i++)
                                __value[i] = global::NrfBleDriver.BleGattcAttrInfo128T.__CreateInstance(*((global::NrfBleDriver.BleGattcAttrInfo128T.__Internal*)&(__arrPtr[i * sizeof(global::NrfBleDriver.BleGattcAttrInfo128T.__Internal)])));
                        }
                        return __value;
                    }
                }

                set
                {
                    fixed (global::NrfBleDriver.BleGattcAttrInfo128T __arrPtr = __instance.attr_info128)
                    {
                        if (value != null)
                        {
                            if (value.Length != 1)
                                throw new ArgumentOutOfRangeException("value", "The dimensions of the provided array don't match the required size.");
                            for (int i = 0; i < 1; i++)
                                *(global::NrfBleDriver.BleGattcAttrInfo128T.__Internal*) &__arrPtr[i * sizeof(global::NrfBleDriver.BleGattcAttrInfo128T.__Internal)] = *(global::NrfBleDriver.BleGattcAttrInfo128T.__Internal*)value[i].__Instance;
                        }
                    }
                }
            }

Going back to the headers, these errors are related with the following structure, more specifically to the internal union info as show below:

/**@brief Event structure for @ref BLE_GATTC_EVT_ATTR_INFO_DISC_RSP. */
typedef struct
{
  uint16_t                     count;            /**< Attribute count. */
  uint8_t                      format;           /**< Attribute information format, see @ref BLE_GATTC_ATTR_INFO_FORMAT. */
  union {
    ble_gattc_attr_info16_t  attr_info16[1];     /**< Attribute information for 16-bit Attribute UUID.
                                                      @note This is a variable length array. The size of 1 indicated is only a placeholder for compilation.
                                                      See @ref sd_ble_evt_get for more information on how to use event structures with variable length array members. */
    ble_gattc_attr_info128_t attr_info128[1];    /**< Attribute information for 128-bit Attribute UUID.
                                                      @note This is a variable length array. The size of 1 indicated is only a placeholder for compilation.
                                                      See @ref sd_ble_evt_get for more information on how to use event structures with variable length array members. */
  } info;                                        /**< Attribute information union. */
} ble_gattc_evt_attr_info_disc_rsp_t;

As mentioned in the header comments, these variables are structures with variable length array.

Please, may I get some suggestion to solve this particular issue in the Preprocess or Postprocess methods?

Thanks in advance

Dominant language
C#
Stars
3.4k
Forks
541
PR merge metrics
No merged PRs in 30d

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from mono/CppSharp

All issues in mono/CppSharp

Similar issues

More C# issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.