1

I use Visual Studio 2015 and I have a C# Application-Project that defines a COM-Interface and generates a .tlb file on compilation. Now I want to import that Csharp.tlb into an idl.

MyLibrary.idl:

import "oaidl.idl";
import "ocidl.idl";
import "Cplusplus.idl";

library MyLibrary
{
  importlib("stdole32.tlb");
  importlib("stdole2.tlb");
  importlib("Csharp.tlb");

  interface IMyCOM : IDispatch
  {
    [propget, id(1)]
    HRESULT CpluplusObject
    (
      [out,retval] ICplusplusObject** cplusplusObject
    );

    [propget, id(2)]
    HRESULT CsharpObject
    (
      [out, retval] ICsharpObject** csharpObject
    );
  }

  coclass MyCOM
  {
    [default] interface IMyCOM;
  };
}

During compilation I get an error

C3646 'csharpObject': unknown override specifier in MyLibrary.tlh

MyLibrary.tlh was auto generated by the compilation and looks as the following

MyLibrary.tlh:

#pragma once
#pragma pack(push, 8)

#include <comdef.h>

namespace MyLibrary {

  struct __declspec(uuid("8e664998-bc93-48e7-adcc-84fc8598cd5d"))
  /* dual interface */ ICplusplusObject;

  _COM_SMARTPTR_TYPEDEF(ICplusplusObject, __uuidof(ICplusplusObject));

  struct __declspec(uuid("388ebf11-05c8-4b86-b2bd-60f0ef38695e"))
  IMyLibrary : IDispatch
  {
    __declspec(property(get=GetCplusplusObject))
    ICplusplusObjectPtr cplusplusObject;
    __declspec(property(get=GetCsharpObject))
    ICsharpObjectPtr csharpObject;

    ICplusplusObjectPtr GetCplusplusObject ( );
    ICsharpObjectPtr GetCsharpObject ( );

    virtual HRESULT __stdcall get_CplusplusObject (
      /*[out,retval]*/ struct ICplusplusObject * * cplusplusObject ) = 0;
    virtual HRESULT __stdcall get_CsharpObject (
      /*[out,retval]*/ struct ICsharpObject * * csharpObject ) = 0;
  }

  __declspec(implementation_key(1)) ICplusplusObjectPtr IMyLibrary::GetcplusplusObject ( );
  __declspec(implementation_key(2)) ICsharpObjectPtr IMyLibrary::GetcsharpObject ( );
}

The error means that ICsharpObjectPtr or ICsharpObject respectively is not known which I understand so far. ICplusplusObjectPtr is known because import "ICplusplus.idl" added the definitions into the .tlh and importlib("ICsharp.tlb"); did not obviously.

For Test reasons I generated the ICsharp.idl out of the .tlb by using OLE/COM Object Viewer and made an import of that idl. The error was gone after that.

But why does the importlib of the .tlb not work directly? I do not want to generate an idl file every time out of the .tlb.

I think that there is an #include "ICsharp.tlh" missing or something to make the type known for the .tlh. But how to tell the idl or the compiler to properly reference the ICsharpObject?

Thank you so much in advance for your help.

MaLe
  • 33
  • 6
  • You are defining methods in the middle of a `library` block. That doesn't make any sense. Methods, naturally, must be part of an interface. – Igor Tandetnik Aug 12 '16 at 04:49
  • 1
    You want to use [`auto_search`](https://msdn.microsoft.com/en-us/library/0346ezww.aspx) attribute with your `#import` directive. Or else explicitly `#import` Csharp.tlb first. – Igor Tandetnik Aug 12 '16 at 04:54
  • I made a correction of MyLibrary.idl code. I just forgot to write down the interface as you noticed already. Thank you. – MaLe Aug 12 '16 at 11:19
  • The #import statement one can use in a cpp file, right? But I want to import a .tlb into an .idl file not a .cpp file. I did this with an importlib ("Csharp.tlb") statement, which leads to this error. If I generated an Csharp.idl out of that Csharp.tlb file I was able to use the import "Csharp.idl" statement and it worked. But I do not want to have this .tld->.idl conversion. – MaLe Aug 12 '16 at 11:27
  • Where did the .tlh file come from? Normally, it's the product of the `#import` statement in your C++ code. Are you saying you don't have such a statement? With all due respect, I find it difficult to believe. – Igor Tandetnik Aug 12 '16 at 12:16
  • If you are confused now then it is going to be much more confusing later. Perhaps you are trying too hard to make it looks like a unified api when it really isn't. This is difficult on the client programmer as well, he has to reference both type libraries without any cue that this is necessary. And installing is rough, two different DLLs with very different registration procedures. And building is rough, changing one requires rebuilding the other. None of this is impossible, it is however much easier to unravel when you keep them separate. – Hans Passant Aug 12 '16 at 12:52
  • Unfortunately the most of it is legacy code. All I want to do is to add another new Project written in C#. All the others were written in c++. So I think I have no choice really if I do not want to break with the existing Interfacing. @IgorTandetnik: Yes you are absolutely right, I do have #Import statements. I get a little confused now with all these Import stuff. Sorry for that. My mind was just sticking to the idls imports. Ah, ok so my Problem seems to be the order of #imports that generate the .tlh's. I will try that. Thank you very much. – MaLe Aug 13 '16 at 20:54

1 Answers1

1

This is an error due to wrong order of tlb-imports. The #import directive tries to generate the primary (.tlh) and secondary (.tli) header files on compilation. If a tlb uses a type of another typelib which was not imported first this error will occur. In this case the following solved the error

Importer.cpp

#import "CplusplusLibrary.tlb"
#import "CsharpLibrary.tlb"
#import "MyLibrary.tlb"

Thank you so much Igor.

MaLe
  • 33
  • 6