How to resolve circular type dependency?

7 posts / 0 new
Last post
Offline
Last seen: 1 year 7 months ago
Joined: 04/10/2023
Posts: 4
How to resolve circular type dependency?

I'm working on a project with complex messages that have something akin to the following pattern in them:

struct TypeA {

TypeB _child; // @resolve-name false

};

struct TypeB {

sequence<TypeA> _sequence; // @resolve-name false

};

 

I've generated C# typefiles using rtiddsgen.bat from version 6.1.1, and they compile, but when I try to CreateTopic on either of the types, I get a null reference exception.

I've discovered that when TypeAPlugin calls CreateDynamicType, it attempts to get TypeBSupport.Instance, which in turn then tries creating a dynamic type for TypeB, which calls TypeASupport.Instance. At this point, exceptions are thrown, and it all fails. 

 

What are my options for handling this?

Howard's picture
Offline
Last seen: 16 hours 24 min ago
Joined: 11/29/2012
Posts: 608

Your example data type is not one that can be compiled by C#.  The definition of the 2 data structures as you wrote is not allowed.

I'm guessing that your actual data type is different somehow.

Please post a valid IDL that both reflects the problem and can be used by rtiddsgen to generate a C# example that can be successfully compiled...but when run, shows the problem.

Offline
Last seen: 1 year 7 months ago
Joined: 04/10/2023
Posts: 4

Thanks for responding.

I've updated the IDL in the original post, so it should successfully generate C# now. One thing I noted, is that the C# that's generated doesn't compile, because when it references TypeAUnmanaged and TypeBUnmanaged, it prepends it with global::Implementation. I had removed the "global::Implementation." namespace to get it to compile, as the classes are defined in the same namespace. Should I have done something else?

 

Actually, on closer inspection, my test code has the structs wrapped in a module, so the namespace is different. It should generate and compile as is.

Offline
Last seen: 1 year 7 months ago
Joined: 04/10/2023
Posts: 4

I've verified that the following IDL generates code that compiles in C#, but attempting to create a topic of either type leads to a null reference exception.

struct TypeA {

TypeB _child; // @resolve-name false

};

struct TypeB {

sequence<TypeA> _sequence; // @resolve-name false

};

The actual data type is different, in that there are more types involved in the loop, and one of those types is a union containing the initial type as one of it's members. I have been told that the pattern works in Java and C++ with version 5.3.1. Is there a particular reason this won't work in C#?

 

Howard's picture
Offline
Last seen: 16 hours 24 min ago
Joined: 11/29/2012
Posts: 608

So, no, this kind of circular dependency is not supported.  I used the attached IDL (note I had to make sure that the TypeB class was predeclared with an //@copy statement).

 

And then generated a C++ application using Connext 5.3.1, compiled and ran.  Basically, it went into an infinite loop with typecode generation.  TypeA typecode generation calling TypeB typecode generation calling TypeA typecode generation, etc.

 

Do you have an working example of what was supported and working in C++/Java?

 

NOTE:  This forum is not an official RTI support channel.  If your project has official RTI support, you should probably try to use that instead of the forum.  However, they will likely come to the same conclusion.  What you've described in your example isn't going to work.

File Attachments: 
Offline
Last seen: 1 year 7 months ago
Joined: 04/10/2023
Posts: 4

Apparently, the working C++ was generated with the -notypecode flag, which is no longer supported. It seems we'll need to restructure. 

Thanks again, Howard!

Howard's picture
Offline
Last seen: 16 hours 24 min ago
Joined: 11/29/2012
Posts: 608

Ah yes.  With Connext 6.x and beyond, the -notypecode flag is no longer supported.  Hope you're able to restructure.