1

Hi I'm trying to create and marshal the following structure from C# into C++ and maintain the linked reference. I'm unsure how this structure should be defined in C#? In C++ the structure must look like below, with the const reference maintained.

// C++
struct {
        int   a;       // my value
  const int&  b = a;   // my reference to a
}

Does anyone know if this is possible?

Thanks.

Edit:

This is more representative of what I'm trying to accomplish, and as pointed out by @Hans it is not legal C++, but maybe someone can suggest a better path? The system_t is generated in either C++ or C# and passed to C++. My best guess: (if this is even a good design pattern) is to initialize all the references in the system_t constructor in C++. As far as marshaling from C#, it will get complicated.

struct system_t
{
  float    sysSampleRate = 112500.0f;            // Sample rate from receivers.
                                                 // Illegal statement @Hans

  struct tvg_t  // tvg_t is passed to tvg processor 
  {
          float    tvgLinearGain;
    const float&   tvgSampleRate = sysSampleRate;   // Get the rate from system.
                                                    // Illegal statement @Hans
  } tvg;   // Nested tvg_t in system_t.

  //... Many other structures and variables ..//
};

I'd like to find the right design pattern rather than abandoning this and going to a flat structure or passing system_t to every module.

Mark
  • 510
  • 1
  • 5
  • 18
  • What exactly is your question? I am going to guess you want to know if you can have a reference value within a structure, of course it doesn't make a great deal of sense to do that in C#, since you can simply pass the entire struct as a reference. – Security Hound Sep 30 '11 at 18:47
  • `b` needs to reference `a` in the C++ code, however the structure is generated in C# and needs to be marshaled. Is it possible to create this sort of structure in C# and marshal it? Would it be an `Int32` and an `IntPtr` in the structure, with the `IntPtr` pointing to `Int32`? – Mark Sep 30 '11 at 18:52
  • 1
    Why bother with the reference if it refers to a field in the struct? That seems perverse. – David Heffernan Sep 30 '11 at 18:59
  • The actual problem has multiple nested structures that share common values, that are linked by reference. – Mark Sep 30 '11 at 19:02
  • Your question needs updating. You need to make it clear that you wish to initialise the reference in the C# code. – David Heffernan Sep 30 '11 at 19:03
  • And as for the answer, I think you should consider alternative approaches. The C# marshalling will be very complex if you insist on assigning pointers to the contents of a struct at the C# side. I guess it could be done but surely there's another way. – David Heffernan Sep 30 '11 at 19:06
  • You could just make `b` private on the managed side so your struct aligns correctly, and then not even worry that it exists. – scottm Sep 30 '11 at 19:10
  • This is not a valid C++ declaration. Only static const integral members can be initialized. It looks bizarre because it isn't legal. – Hans Passant Sep 30 '11 at 19:17
  • I'm going to edit the question to make it a bit clearer and closer to the actual problem. :) – Mark Sep 30 '11 at 19:20
  • @HansPassant - Looks like it will be legal in C++11 ... ... ... – Mark Sep 30 '11 at 20:10
  • @Mark do you really need the struct on the managed side? Can you just make a managed class that represents the data you need? Marshal the struct you get and pass the necessary values to the class. – scottm Sep 30 '11 at 20:30
  • Thanks, I've decided to take a similar easier approach. – Mark Sep 30 '11 at 21:53

1 Answers1

1

This should work:

[StructLayout(LayoutKind.Sequential)]
public struct MyCStruct {
  public int a;
  public IntPtr b;
}
scottm
  • 27,829
  • 22
  • 107
  • 159
  • Is it reasonable to make `b` constant/readonly in the structure, and initialize it to point at `a` in the constructor? – Mark Sep 30 '11 at 18:59
  • How would you suggest doing that? When you marshal it from C++, b is going to be the unmanaged pointer address. – scottm Sep 30 '11 at 19:06
  • Right, what was I thinking, doh. I like the idea of making it private on the managed side. – Mark Sep 30 '11 at 19:14
  • I believe this layout will suit your need, but you are going to have to allocate and initialize this structure in native code and marshal it back when you construct one of these on the managed side. If I we're doing it I'd make it an internal private structure and wrap access with managed properties. This seems complicated to me if it's new development, but perhaps necessary if adapting to native existing code. – Damon8or Sep 30 '11 at 21:04
  • Agreed - I've made this over complicated and decided to simplify. @scottm thanks for the help – Mark Sep 30 '11 at 21:52