locked
#pragma make_public, ClsCompliantAttribute and LNK2022 errors RRS feed

  • Question

  •  

    I am getting the following VC8 linker error on my mixed assembly which is comprised of old syntax MEC++.

    TextElement.obj : error LNK2022: metadata operation failed (80131195) : Custom attributes are not consistent: (0x0c0002fa). LINK : fatal error LNK1255: link failed because of metadata errors

    I ran ildasm on the above .obj and 0x0c0002fa appears to be the CLSCompliant attribute on a native type for which I have specified #pragma make_public in one of my compilands. I don't have any idea how to make the linker happy here. Not specifying make_public on the type makes the linker error go away, but I need the type to be made public since it is in the signature of a few public methods. Below is the VC8 ildasm output, and below that I have provided the VC7.1 ildasm output.  I have no problem compiling and linking this same source using VC 7.1

    For what it is worth, the textParamWide type is a native POD struct.  No constructors, no vtable, no methods at all.  I certainly see some difference between these two, but not in the CLSCompliant attribute. What inconsistency might the linker be talking about?

    VC8:

     // TypeDef #356 (02000165)
    // -------------------------------------------------------
    //  TypDefName: textParamWide  (02000165)
    //  Flags     : [Public] [SequentialLayout] [Class] [Sealed] [AnsiClass] [BeforeFieldInit]  (00100109)
    //  Extends   : 0100000C [TypeRef] System.ValueType
    //  Layout    : Packing:0, Size:208
    //  CustomAttribute #1 (0c0002f8)
    //  -------------------------------------------------------
    //   CustomAttribute Type: 0a000003
    //   CustomAttributeName: Microsoft.VisualC.MiscellaneousBitsAttribute :: instance void .ctor(int32)
    //   Length: 8
    //   Value : 01 00 41 00 00 00 00 00                          >  A             <
    //   ctor args: (65)
    //
    //  CustomAttribute #2 (0c0002f9)
    //  -------------------------------------------------------
    //   CustomAttribute Type: 0a000002
    //   CustomAttributeName: Microsoft.VisualC.DebugInfoInPDBAttribute :: instance void .ctor()
    //   Length: 4
    //   Value : 01 00 00 00                                      >                <
    //   ctor args: ()
    //
    //  CustomAttribute #3 (0c0002fa)
    //  -------------------------------------------------------
    //   CustomAttribute Type: 0a00000e
    //   CustomAttributeName: System.CLSCompliantAttribute :: instance void .ctor(bool)
    //   Length: 5
    //   Value : 01 00 00 00 00                                   >                <
    //   ctor args: ( <can not decode> )
    //
    //  CustomAttribute #4 (0c0002fb)
    //  -------------------------------------------------------
    //   CustomAttribute Type: 0a000004
    //   CustomAttributeName: System.Runtime.CompilerServices.NativeCppClassAttribute :: instance void .ctor()
    //   Length: 4
    //   Value : 01 00 00 00                                      >                <
    //   ctor args: ()
    //

    VC7.1:

    // TypeDef #260 (02000105)
    // -------------------------------------------------------
    //  TypDefName: textParamWide  (02000105)
    //  Flags     : [Public] [SequentialLayout] [Class] [Sealed] [AnsiClass]  (00000109)
    //  Extends   : 0100000B [TypeRef] System.ValueType
    //  Layout    : Packing:1, Size:208
    //  CustomAttribute #1 (0c0000af)
    //  -------------------------------------------------------
    //   CustomAttribute Type: 0a000001
    //   CustomAttributeName: Microsoft.VisualC.MiscellaneousBitsAttribute :: instance void .ctor(int32)
    //   Length: 8
    //   Value : 01 00 41 00 00 00 00 00                          >  A             <
    //   ctor args: (65)
    //
    //  CustomAttribute #2 (0c0000b0)
    //  -------------------------------------------------------
    //   CustomAttribute Type: 0a000a16
    //   CustomAttributeName: System.CLSCompliantAttribute :: instance void .ctor(bool)
    //   Length: 5
    //   Value : 01 00 00 00 00                                   >                <
    //   ctor args: ( <can not decode> )
    //
    //  CustomAttribute #3 (0c0000b1)
    //  -------------------------------------------------------
    //   CustomAttribute Type: 0a000036
    //   CustomAttributeName: Microsoft.VisualC.DebugInfoInPDBAttribute :: instance void .ctor()
    //   Length: 4
    //   Value : 01 00 00 00                                      >                <
    //   ctor args: ()
    //

    -Bern McCarty

    Friday, September 22, 2006 12:51 AM

Answers

  • The diagnostic tells you that the custom attribute in TextElement.obj is not consistent with a definition in another object file. You need to compare that with the other object files contributing to your image. Ideally, oc, the diagnostic would tell you the other object file. But then, I can imagine how VC link.exe is based on CLR scope merging APIs, which makes this a bit more difficult.

    That being said, I have no idea what would cause the different semantics here. About the only idea I can come up with, that you include the header with the textParamWide definition from two translation units which have incompatible assembly-scope ClsCompliant attributes (and even that doesn't sound very likely)

    -hg 

    Friday, September 22, 2006 8:11 AM

All replies

  • The diagnostic tells you that the custom attribute in TextElement.obj is not consistent with a definition in another object file. You need to compare that with the other object files contributing to your image. Ideally, oc, the diagnostic would tell you the other object file. But then, I can imagine how VC link.exe is based on CLR scope merging APIs, which makes this a bit more difficult.

    That being said, I have no idea what would cause the different semantics here. About the only idea I can come up with, that you include the header with the textParamWide definition from two translation units which have incompatible assembly-scope ClsCompliant attributes (and even that doesn't sound very likely)

    -hg 

    Friday, September 22, 2006 8:11 AM
  • I ended up encountering the very same problem with a 2nd, vastly simpler mixed dll with far fewer objects and I stumbled onto a workaround for both occurances of the problem.  The solution appears to be to issue your #pragma make_public statements in the first .obj presented to the linker.  All that I had to do was switch the order that I presented the .obj files to the linker (I just moved one to be first) and the problem is gone.

    Having discovered that solution I could imagine that my various .obj's had different visibilities for the same native type or something - because some of them defined the native type but didn't do make_public on it, while one of my .objs did both.  But if that is it the linker's error message for a type visibility inconsistency then it sure needs improved.  It seems that the real problem had nothing at all to do with the CLSCompliant attribute.

    -Bern McCarty

    Friday, September 22, 2006 7:29 PM
  • On a second thought its actually fairly obvious that non-exported types don't need the ClsCompliant attribute because -- well, they aren't visible outside the assembly anyway. So there are no consumers that would possibly care. So maybe the compiler only emits the attribute if the type is indeed visible outside the assembly.

    Why reordering the input solves the problem is beyond me and indeed the diagnostic is quite a bit insideous. That being said, you'll probably want to use make_public consistently, anyway (i.e. place it in the header file).

    -hg

    Friday, September 22, 2006 11:10 PM
  • I just encountered a similar problem here.  The error was observable in the output of ildasm as illustrated below:

     

    // CustomAttribute #2 (0c000015)

    // -------------------------------------------------------

    // CustomAttribute Type: 0a000005

    // CustomAttributeName: System.CLSCompliantAttribute :: instance void .ctor(bool)

    // Length: 5

    // Value : 01 00 00 00 00                                   >                <

    // ctor args: ( <can not decode> )

    //

     

    In my case, I had two header files, say 'utilities.h' and 'other.h' and by necessity I had the following pragma statement in each:

    #pragma make_public(OURAPI::Core::SafeString)

    However, my 'other.h' #includes utilities.

    It really did not feel right but to work around this, I could only keep my #pragma statement within the utilities header and had to leave it out of the other header.

     

    This is a reasonably old thread but I figured i'd add my two cents.

     

    Any thoughts?

    Joseph Armbruster

    Monday, July 26, 2010 6:39 PM