C# autogen's "copy_from" for enum type

8 posts / 0 new
Last post
Offline
Last seen: 11 years 1 week ago
Joined: 02/05/2013
Posts: 16
C# autogen's "copy_from" for enum type

Hello-

We have a scenario where we autogen the same set of IDL files for Java, C++, and C#.  This IDL contains an enumeration type with IDs in one file and a struct type in another file with a single member of this enumerated ID type.  I don't believe the file seperation is actually contributing to the problem but I haven't determined this conclusively yet.

Rtiddgen properly creates the Java & C++ code fine, but when we autogen to C# the resulting cpp code is attempting to reference a ::copy_from() method that does not exist in the associated header file.

Example IDL:

module General {
    enum IDLType_General_EventID {EVENT_END_OF_SEQUENCE};
    struct IDLType_General_Event {
       IDLType_General_EventID event; //@key
    }; //@resolve-name LANG_SPEC
     //@top-level true
}

(Note in above that LANG_SPEC is a key we use for pre-processing the IDL as we have observed differences in behavior between different language targets but thats a topic for another time.  LANG_SPEC == true for c++ and false in all other cases.  We use -namespace).

Resulting code that is generated:

System::Boolean IDLType_General_Event::copy_from(IDLType_General_Event^ src)
{
IDLType_General_Event^ dst = this;
dst-> event->copy_from(src->event);
return true;
}

Building under MSVS 2010 we end up with the error :

Error 39 error C2039: 'copy_from' : is not a member of 'General::IDLType_General_EventID' C:\obs.betaWC\csharp\libbiztypes_csharp\src\IDLTypes_General.cpp 555 1 IDLTypes_cs

 

I've admittedly not boiled this down to a very simple, exportable example and am hoping you might off some insight without investing in that effort.  I will investigate further and reduce this to a very simple example if needed.

Any insight would be greatly appreciated.

-Todd Moody

 

Offline
Last seen: 11 years 1 week ago
Joined: 02/05/2013
Posts: 16

I created a simple example.

The IDL:

module Test {
    enum TestEnum {
        ID_1,
        ID_2
    };
     struct TestType {
        TestEnum id;
    }; //@resolve-name false
    //@top-level true
    };

Built using the following command line:

rtiddsgen.bat -inputIdl -ppDisable -replace -language C# -d ../../../../csharp/libbiztypes_csharp/temp preprocessed/csharp/TestEnum.idl

There are a total of 5 build errors that I believe are all related to the resolve-name = false but the first is:

Error 1 error C2039: 'copy_from' : is not a member of 'Test::TestEnum' C:\obs.betaWC\csharp\libbiztypes_csharp\src\TestEnum.cpp 102 1 IDLTypes_cs

If I change resolve-name to true, this builds fine.

Interesting resulting code with resolve-name = false (does not compile):

System::Boolean TestType::copy_from(TestType^ src) {
    TestType^ dst = this;
    dst->id->copy_from(src->id);
  return true;
}

Furthmore inside TestType, the single field is defined as:

TestEnum^ id;

With resolve-name = true (compiles):

System::Boolean TestType::copy_from(TestType^ src) {
    TestType^ dst = this;
  
dst->id = src->id;
    return true;
}

 Furthmore inside TestType, the single field is defined as:

Test::TestEnum id;

As I described in the previous post, however, we control this universally for language targets across many IDL files and it has worked for Java & C++ well. This becomes an exception that I don't understand.

-Todd

Offline
Last seen: 11 years 1 week ago
Joined: 02/05/2013
Posts: 16

Ok a final perplexing example that is more representative of our IDL arrangement.  I cannot get this to compile in any arrangement of resolve-name and/or namespace options.

File #1: TestEnumAndConstants.idl:

module Test {
    module EnumsAndConstants {
       enum TestEnum {
             ID_1,
             ID_2
        };
      
        // Constants
        const long EXAMPLE_ARRAY_LENGTH = 2;
    };
};    

File  #2:TestType.idl

//@copy-cppcli #include "TestEnumAndConstants.h"
//@copy-cppcli #include "TestEnumAndConstantsPlugin.h"
//@copy-cppcli using namespace Test::EnumsAndConstants;

module Test {
    module Type {
       struct TestType {
             TestEnum  id; 
             double    exampleArray[ EXAMPLE_ARRAY_LENGTH ]; //@resolve-name false
       };
   };
};  

Note 1: If I do not include "resolve-name false", then the autogen'd code attempt to access EXAMPLE_ARRAY_LENGTH directly as an integer value though it is a class.  Using resolve-name false has the unexpected behaviour of causing the autogen'd code to properly access the value as EXAMPLE_ARRAY_LENGTH::VALUE

Note 2: I have extra #includes & "using namespace"  in an attempt to get this to compile but cannot.

Using or not using -namespace seems to have no affect (which I think it expected per the RTI User's Manual but its not entirely clear).

Please advise of my mistake(s) and how this intent can be accomplished with C#.

I should add that we are using Connext 5.0.

-Todd

 

 

 

 

 

JavierPovedano's picture
Offline
Last seen: 1 year 8 months ago
Joined: 06/05/2013
Posts: 16

Hi Todd,

The IDL compiler needs to know at compile time how to resolve the different types present on the IDL file in order to generate code that follows the scoping rules of the target language. For this reason, the recommended way to define types that contains other types from other module/namespaces is by using idl #include directives and their fully qualified domain name. The advantages of this approach are:

  • The IDL compiler will resolve the names for you in the generated code. Hence, is not necessary to use per-language directives such as  //@copy-cppcli
  • The resolve-name directive is no longer necessary, making the IDL files easy to understand.

According to these guidelines, your types would be defined like this:

File TestEnumsAndConstants.idl: 

module Test { 
    module EnumsAndConstants { 
        enum TestEnum { 
            ID_1, 
            ID_2 
        }; 

        // Constants 
        const long EXAMPLE_ARRAY_LENGTH = 2; 
    }; 
}; 


File TestType.idl: 

#include "TestEnumsAndConstants.idl" 

module Test {
    module Type {
        struct TestType {
            Test::EnumsAndConstants::TestEnum id;
            double exampleArray[ Test::EnumsAndConstants::EXAMPLE_ARRAY_LENGTH ];
        };
    };
};

 

The code generated from these IDL files builds in C++/Java and C#. 

 

Offline
Last seen: 10 years 1 week ago
Joined: 11/18/2014
Posts: 2

Hi Javier,

I have a similar problem to Todd.  I've tried to recreate your code locally, but compiling in C# throws up a number of errors. The "error C2039: 'copy_from' : is not a member of 'Test::EnumsAndConstants::TestEnum' still exists in my build.  Can you see from the code below where I might have gone wrong?

TestType.idl

#include "TestEnumsAndConstants.idl"

module Test {

module Type {

struct TestType {

Test::EnumsAndConstants::TestEnum id;

long exampleArray[ Test::EnumsAndConstants::EXAMPLE_ARRAY_LENGTH ];

};

};

};

 

TestEnumsAndConstants.idl

module Test {

module EnumsAndConstants {

enum TestEnum {

ID_1,

ID_2

};

// Constants

const long EXAMPLE_ARRAY_LENGTH = 2;

};

};

 

I build these using:

rtiddsgen -inputIDL "TestEnumsAndConstants.idl" -namespace -ppDisable -replace -language C#

rtiddsgen -inputIDL "TestType.idl" -namespace -ppDisable -replace -language C# -example i86Win32dotnet4.0

Neil.

Offline
Last seen: 10 years 1 week ago
Joined: 11/18/2014
Posts: 2

UPDATE:

Solution provided by Sonia at RTI support: I was passing -ppDisable to rtiddsgen when I should have been passing a switch to the pre-processor.  Replace -ppDisable with -ppPath "C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\bin\cl.exe" -ppOption /nologo -ppOption /C -ppOption /E -ppOption /X

All working now.

Offline
Last seen: 7 years 5 months ago
Joined: 02/22/2015
Posts: 1

Check this one..More about .... Enum

http://csharp.net-informations.com/statements/enum.htm

Tomi

 

jwillemsen's picture
Offline
Last seen: 3 years 6 months ago
Joined: 09/24/2013
Posts: 55

Just a small note that annotations with a - in the name are not legal in the formal IDL syntax