importing a type lib with a module results in empty class

Locked importing a type lib with a module results in empty class

  • 27. října 2011 15:46
     
     

    We have a typelib where we define some constants. One of our sets of constants is created using the module keyword:

    module MyConstants

    {

    const int Const1 = 1;

    };

    I use tlbimp.exe in a bat file to generate a primary interop assembly for internal use.

    If I create a VB .net project and add a reference and browse to the .tlb file and import it, the result I see in the browser window is a class named MyConstants. If I click the class, the right hand pane is empty - the class contains absolutely nothing.

    If I add a reference to the primary interop assembly, I also see the class MyConstants int he browser window. When I click the class, the constants show up.

    This is in Visual Studio 2010 (RTM). Why does VB .NET add reference via brwose to the .tlb file differ in this case? Is this a bug in VB .NET or the tlbimp.exe tool?


    R.D. Holland

Všechny reakce

  • 31. října 2011 5:55
     
     

    Hi Holland,

    It should be not a bug.

    Have a nice day.


    Call me ghost for short, Thanks
    To get the better anwser, it should be a better question.
  • 31. října 2011 15:16
     
     
    Ghost, Then why the difference?
    R.D. Holland
  • 1. listopadu 2011 4:44
    Moderátor
     
     

    Hi Holland,

    Welcome to the MSDN Forum.

    Please take a look at this article: http://msdn.microsoft.com/en-us/library/windows/desktop/aa366757(v=vs.85).aspx

    It shows what is tlb file.

    A type library (.tlb) is a binary file that stores information about a COM or DCOM object's properties and methods in a form that is accessible to other applications at runtime. Using a type library, an application or browser can determine which interfaces an object supports, and invoke an object's interface methods. This can occur even if the object and client applications were written in different programming languages. The COM/DCOM run-time environment can also use a type library to provide automatic cross-apartment, cross-process, and cross-machine marshaling for interfaces described in type libraries.

    The constant is not a property neither a method, so you can not found it in tlb file.

    Best regards,


    Mike Feng [MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

  • 1. listopadu 2011 13:35
     
     

    Mike,

    Thanks for the reply. I am fairly familiar with midl and .tlb files having developed them, and against them for a lot of years.

    The fact is I can open the typelib in oleview and I can see the constants in the module. And I can run tlbimp.exe to generate a primary interop assembly and then add a ref to the assembly in a .net project and I can see the constants in a class into which the module was converted.

    The only issue I have is that when a user adds a reference directly to the .tlb file, the class into which the module is created is devoid of the constants. Now tlbimp is (or should) be used by the IDE when importing a .tlb file. So my query is about the actual difference users are seeing between the indirect, and direct, use of tlbimp.

    I would note that I did not register the primary interop assembly (and of course it is not in the GAC). So when adding a ref directly to the .tlb file, the IDE does not accidently/automatically bind to the PIA.

    I didn't actually put the constants into the module. I usually create enums (neither a property nor a method either) and that has not been an issue. In this case the intent appears to be to allow logical or of the values for method parameters.


    R.D. Holland
  • 2. listopadu 2011 9:47
    Moderátor
     
     

    Hi Holland,

    >>The only issue I have is that when a user adds a reference directly to the .tlb file.

    How do you directly add a reference to a .net project? Please tell me the steps, so I can reproduce your scenario.

    Best regards,


    Mike Feng [MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

  • 2. listopadu 2011 18:18
     
     

    right click the project in the solution explorer and choose properties. On the properties UI click the "references" item/tab. In the references UI click the "Add" button. The "Add Reference" dialog appears. There is a browse tab on the dialog. Click it. Then browse to a directory that has a .tlb file in it and simply pick the .tlb file.

    The IDE will import the .tlb file as an interop assembly. So it has to be either using tlbimp.exe or it has its own tlb importer (which could be why I see a difference). Additionally, if nothing goes wrong, the properties page for the newly added reference will have the "Copy Local" value set to true and the interop assembly that is converted from the .tlb file will be in one of your project's sub folders.

     

     

    One caveat you can enounter - If you have ever run tlbimp.exe on the .tlb file you chose and you used the /primary option for tlbimp.exe AND you either registered the resulting interop assembly via regasm or you dropped it into the GAC (which registers it), the IDE can end up displaying a message in the "Path" column of the "References" UI telling you that the file could not be found for the reference you just added. That will happen if you have deleted the PIA from the GAC (that fails to unregister all the entries previously registered when you dropped it into the GAC) OR you have deleted it from the dir on which you previously ran regasm manually. To recap this bug, you can browse to a .tlb file and click OK and the UI tells the user the "file could not be found". You then sit there and wonder how you could browse to the file, click it, hit "OK" and the IDE cannot find that file!

    To resolve that issue, one must display the properties window so the CLSID of the type lib can be noted when you click the newly added ref in the "References" table. Then you have to open the registry and find the entry for the type lib. The registry will have a "primary interop assembly" entry that has the path to the GAC or where ever the PIA was when you ran regasm.exe on it. You have to delete that entry from the registry, delete the reference and re-add the .tlb file again.

    If the PIA is still in the GAC or located where it was if you registered it manually via regasm, even though you browsed to the .tlb file, the "Path" column will tell you the reference is in the GAC or point to the file on disk you ran regasm on. In this case, until you zap the reg entry pointing to the PIA, you cannot change the "Copy local" option in the properties window.

    Note that this anomaly/bug was introduced in VS 2008. With VS 2005, if a PIA exists and is registered with the type library file, when you import the .tlb file via the add references browse UI, you immediately get a local copy of the converted interop assembly. I'm surprised that MS has failed to fix that issue in VS 2010.


    R.D. Holland
  • 3. listopadu 2011 3:33
    Moderátor
     
     

    Hi Holland,

    Please refer to this picture:

     

     

    It tells me I cannot add an Active type library to a .net Framework. And I take it as reasonable, as I mentioned above, A type library (.tlb) is a binary file that stores information about a COM or DCOM object's properties and methods in a form

    So you may need to tell me how do you make the DLL/tlb file.

    Best regards,


    Mike Feng [MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

  • 3. listopadu 2011 21:39
     
     

    Mike,

    You exported a type lib from a .net assembly and tried to import that as a type lib. That's different and uses a different tool - tlbexp.exe. I imported a type library using tlbimp.exe to create an interop (.NET) assembly. You either ran tlbexp.exe manually, or exported a type lib from the IDE. Actually I have not exported a COM type lib directly from the IDE but I assume it can be done, probably when using the "Register for COM interop" and after exposing some interface on a .net class to COM.

    What I have done is to build a non .NET project (C++ code) that has a source .idl file that is compiled via the midl compiler. The result is a .tlb file. I then open the vb.net project and perform the steps I mentioned above.

    Trust me. One can add a .tlb file as a reference and the IDE automatically creates an interop assembly using the steps I mentioned.

     


    R.D. Holland