0

I have an interface IFoo that references the Office typelib MSO.DLL. I want the proxy/stub code (dlldata.c) to be generated for my interfaces when my IDL is compiled. As I understand it, in order for midl.exe to produce the proxy/stub code, the interface(s) must be declared at the root level of my IDL. However, the importlib statements can only be within the library block. Consequently, the type I'm trying to reference (Office._CustomXMLParts) doesn't exist when IFoo is compiled. Is there any way to solve this, other than custom proxy/stub implementation or using IDispatch instead of the full referenced type?

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

[
    object,
    uuid(02F84D34-91DB-400B-94C9-71ABCD6F077D),
    version(1.0),
    nonextensible,
    pointer_default(unique),
    oleautomation,
    dual
]
interface IFoo : IDispatch
{
    [id(0x461A47A4)] HRESULT Bar([in] Office._CustomXMLParts* customXmlParts);
};

[
    uuid(CC76135E-FA22-4437-8719-3FFADE38D72B),
    version(1.0)
]
library FooLib
{
    importlib("stdole2.tlb");
    importlib("mso.dll");

    interface IFoo;
}

The error I receive is:

error MIDL2025: syntax error : expecting a type specification near "Office"

I tried moving the interface definitions below the library block, but I get a different error.

error MIDL2009: undefined symbol : _CustomXMLParts [ Parameter 'customXmlParts' of Procedure 'Bar'  ]
Michael Gunter
  • 12,528
  • 1
  • 24
  • 58
  • Ah rats, you misspelled the interface name. It is `Office::_CustomXMLParts`, XML in capitals. You must `#import "mso.dll"` in your .cpp files so the compiler knows the definition of the interface, it can't get it from the IDL. – Hans Passant Nov 22 '16 at 17:41
  • Casing doesn't really matter in IDL, as all type library and IDispatch operations are supposed to be case-insensitive. Changing the case here has no effect. My results are the exactly same no matter what case I use. – Michael Gunter Nov 22 '16 at 17:43
  • FWIW: I updated my post with the correct casing. Question stands. – Michael Gunter Nov 22 '16 at 17:48
  • Rats because I lost half an hour of my life trying to get it to compile. C++ is most certainly case-sensitive, unlike VB. And requires `::`, not `.` to match the #import definitions. I get a clean build for a sample ATL project with a proxy/stub, the #import directive is essential. Good luck. – Hans Passant Nov 22 '16 at 17:49
  • I know you know this stuff well, Hans, but you're a little off your game today. :) C++ is case sensitive. IDL is not. I just ran a test where I use OFFICE._CUSTOMXMLPARTS instead of the "correct" casing. With the interface definitions in the library block, even this totally wrong casing compiles fine in the IDL. The C++ is always produced with the correct casing. The MIDL compiler doesn't care what case you use -- it always produces the correct case for the C++. `HRESULT ( STDMETHODCALLTYPE *Bar )( IFoo * This, /* [in] */ /* external definition not present */ _CustomXMLParts *customXmlParts);` – Michael Gunter Nov 22 '16 at 17:55
  • Ultimately, this is not my question, though. It doesn't matter which type library I use, or which case I use to refer to the type library or the type. The problem is that I can't seem to use IDL to produce proxy/stub code as long as my interface uses an external type, since I can't produce proxy/stub code with the interface definitions in the `library` block, and I can't `importlib` the external type library outside the `library` block. – Michael Gunter Nov 22 '16 at 17:57
  • Try to focus less on what I might have done wrong or how I did not answer the question, more on getting that Bar declaration to compile. To match the declaration that was #imported from mso.dll, it requires either `Office::_CustomXMLParts` or you'll have to squirrel a `using namespace Office;` somewhere. It is still not obvious whether you actually used #import. Required. – Hans Passant Nov 22 '16 at 18:11
  • @HansPassant: Please try to focus on my question. :) I know full well that I need to `#import "mso.dll"` and had already done so before asking this question. I'm not talking about the C++. I'm talking about the IDL. With the interface declarations outside the library block, the IDL does not compile (and therefore does not produce any C++). With the interface declarations inside the library block, the IDL compiles, but it does not produce the C++ for the proxy/stub (dlldata.c). Everything else I fully know how to deal with. – Michael Gunter Nov 22 '16 at 18:14
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/128744/discussion-between-michael-gunter-and-hans-passant). – Michael Gunter Nov 22 '16 at 18:33
  • [`oleview`](https://msdn.microsoft.com/en-us/library/d0kh9f4c.aspx) can generate IDL from TLB. I haven't tried actually compiling the result though. – Igor Tandetnik Nov 22 '16 at 20:32
  • I don't have a TLB because my IDL won't compile when the interface declarations are at the root (as required to produce dlldata.c). – Michael Gunter Nov 22 '16 at 20:33
  • I meant, generate IDL from mso.dll, then `import` that (just like you do `oaidl.idl`, say). – Igor Tandetnik Nov 22 '16 at 20:47
  • I'll try that. I've never used imports other than the standard. I half expect it to try to put the defined interfaces into my type library, but maybe that's not the case. Thanks. – Michael Gunter Nov 22 '16 at 22:24

0 Answers0