locked
How to share structure with arrays in a single file between C# and C with arrays? RRS feed

  • Question

  • It is possible to define things so that a file that contains a struct definition can be included in both C# and C programs once the differences are taken into account. Most of these differences can be handled but not all. One of those problems is arrays.

    Here's a contrived example of a file that can be imported directly into either a C or a C# project. If '__c__' is defined then the file is being imported into a C++ project. If not then the file is being consumed by a C# project. This simple little thing allows those things that are different between the two environments to be taken into consideration. The one really knotty problem is how to handle arrays. In C, an array can be given a fixed size in a struct. Not so in C#. C# generates a compile time error. I've been working around it so far by numbering the elements in the C# branch.

    // If '__c__' is defined then the file is being included in a C project.
    // If not then the file is being included in a C# project.

    #if !__c__ // C# can utilize a namespace. C cannot. namespace CrossPlatform { // C# wants to include the struct in a class. public class Structs { #endif #if __c__ // C defines a struct as a named typedef. typedef struct _RtInfo #else // C# wants a struct object with a name. public struct RtInfo #endif {
    // Simple value types and previously defined structures
    // can be shared directly between both C and C#.
    float f; #if __c__ // Arrays cannot be shared. C can use arrays with a size. int v[4]; #else // but C# cannot deal with sized arrays at all. int v0; int v1; int v2; int v3; #endif #if __c__ // C optionally gives the struct a name. } CALDATA; #else // C# does not do that here. } #endif #if !__c__ } // end of class. } // end of namespace block wrapper. #endif



    Richard Lewis Haggard


    Wednesday, February 4, 2015 5:33 PM

Answers

  • In C# you can write ‘int [] v’ and you have to initialise it with ‘new int[4]’ (This can be done inside a constructor if you use class instead of struct). System will allocate such values outside the structure.

    If you need a C# structure which will be transferred to C as a structure with embedded array, then consider the [MarshalAs] attribute.

    It depends on the purposes.

    • Marked as answer by Kristin Xie Sunday, February 15, 2015 9:38 AM
    Wednesday, February 4, 2015 7:42 PM

All replies

    • Proposed as answer by bouzidmed Wednesday, February 4, 2015 8:41 PM
    • Unproposed as answer by Richard.Haggard Wednesday, February 4, 2015 10:10 PM
    Wednesday, February 4, 2015 7:35 PM
  • In C# you can write ‘int [] v’ and you have to initialise it with ‘new int[4]’ (This can be done inside a constructor if you use class instead of struct). System will allocate such values outside the structure.

    If you need a C# structure which will be transferred to C as a structure with embedded array, then consider the [MarshalAs] attribute.

    It depends on the purposes.

    • Marked as answer by Kristin Xie Sunday, February 15, 2015 9:38 AM
    Wednesday, February 4, 2015 7:42 PM
  • Neither of those links addressed the question.

    Richard Lewis Haggard

    Wednesday, February 4, 2015 10:15 PM
  • Thanks for the response. The idea of using a class instead of a struct is interesting. Thank you. I'll investigate it further. The missing piece of this particular puzzle is that the struct is being passed in to the C# code from an embedded device which is, of course, programmed using C (not C++) as a byte array. I would prefer to implement the conversion from a byte array to a struct through a generic software mechanism that knows how to create any struct object from a byte array. Changing the C# specific portions of the struct to a class and then implementing a class specific serializer/deserializer might be reasonable but I'll have to investigate it further.

    Richard Lewis Haggard

    Wednesday, February 4, 2015 10:23 PM
  • See also PtrToStructure [https://msdn.microsoft.com/en-us/library/vstudio/4ca6d5z7(v=vs.100).aspx], which transfers (deserializes) an array of bytes to structure, taking into consideration [MarshalAs] and [StructLayout] directives.

    You can also write some portions of your C# application in a C++/CLR Class Library, where you can include and access your C structure and convert to managed object explicitly.


    • Edited by Viorel_MVP Thursday, February 5, 2015 6:06 AM
    Thursday, February 5, 2015 6:02 AM
  • Hi Richard.

    Would you mind letting us know the result of the suggestion?

    I temporarily mark Viorels last response as an answer. You can unmark it if they provide no help.

    Best regards,

    Kristin



    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey.

    Sunday, February 15, 2015 9:38 AM