Getting IDL (for TLB) from a COM+ dll when it is not provided
Asked Answered
C

1

5

I have a .dll that contains some directshow filters (COM) with specific/custom interfaces to query.

Most 3rd party directshow components contain embedded .tlb files that can be used for cross-enviroment communication (C# typelib import).

I would hate to have to attempt to manually create the interfaces needed for c# because no idl/tlb files were provided.

Is it possible to generate a tlb (or at least, an idl, which I can MIDL compile) from a COM .dll?

Clumsy answered 22/8, 2013 at 16:12 Comment(8)
Take a look at tlbexp.exePesky
Isn't that only for .NET assemblies? [ComVisible]Clumsy
No. You are yelling for help in a crowded soccer stadium. There's a programmer somewhere that can give you exactly what you need. The odds you'll find him here are zilch. Pick up the phone and give him a call. If he doesn't want to help then that's where it ends.Indiscriminate
What phone should I use?Clumsy
How do you know the interface specs in the first place? You mentioned you would hate creating them manually, do you have any documentation on those?Respondent
3rd party gave me c++ com interop interfaces. I need the tlb so I can generate the same interfaces for c#.Clumsy
Apparently they gave you a C++ header file (which itself is a product of MIDL compiler). To my knowledge, a tool which could decompile it back to IDL doesn't exist. You best bet is to contact your supplier and ask for a IDL file, as @HansPassant has suggested.Respondent
Possible duplicate of How to get IDL from a .NET assembly (or how to to convert TLB to IDL) in a command line?Kazue
F
7

Yes, it is possible to reverse engineer/disassemble IDL (or something very close to it). What you need to do is give yourself a new C++ Console Project which gives the default code of

#include "stdafx.h"

int _tmain(int argc, _TCHAR* argv[])
{
    return 0;
}

and then you insert an #import statement underneath the #include statement. So I have been playing with C# assembly marked up to function as a COM Interop DLL and I have called it ComExample2 and it lives in the same solution as the C++ console project that I added which means I can use a nice relative pathname. So my #import statement looks like

#import "..\ComExample2\bin\Debug\ComExample2.tlb" no_namespace named_guids

Then you build your console application. If you delve into the files generated during the build you will find a file that ends with .TLH which stands for type library header. So my path is

..\ComExample2\ConsoleApplication1\Debug\comexample2.tlh

Inside my file is something which looks very much like idl. Here is an edited snippet to give you a flavour....

struct __declspec(uuid("515b1b18-1602-4d42-b743-f1b3c458a0d0"))
/* LIBID */ __ComExample2;
struct /* coclass */ ComExampleClass2;

//
// Type library items
//

struct __declspec(uuid("713007fe-e74c-4fec-b91a-5ef8df279929"))
IFoo : IDispatch
{
    //
    // Wrapper methods for error-handling
    //

    _bstr_t Greeting ( );
    long Sim (
        long a,
        long b );

    //
    // Raw methods provided by interface
    //

      virtual HRESULT __stdcall raw_Greeting (
        /*[out,retval]*/ BSTR * pRetVal ) = 0;
      virtual HRESULT __stdcall raw_Sim (
        /*[in]*/ long a,
        /*[in]*/ long b,
        /*[out,retval]*/ long * pRetVal ) = 0;
};

struct __declspec(uuid("efe233b5-8ab3-4414-855e-1f027e0a72d5"))
ComExampleClass2;
    // interface _Object
    // [ default ] interface IFoo

All of this is generated code so that you can script C++ code against a COM library easily. You'll have to pick through what you need but hopefully that should be enough.

Kind regards,

Lord BattenBerg

Fordham answered 13/1, 2014 at 21:29 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.