问题
I am attempting to create a C# inproc server for sbtsv.idl
(it is included with the Windows 8 SDK). Almost every instructions I find tell you to use MIDL
to create a .tlb
file then tlbimport
to create the proxy dll.
However, if the IDL does not include a library
section no .tlb file will be generated, and sbtsv.idl
does not include a library
section.
I tried creating my own IDL file that declared the interface I wanted to create inside a library
#include "C:\Program Files (x86)\Microsoft SDKs\Windows\v7.1A\Include\sbtsv.idl"
[uuid(43250D0C-BBC6-4109-BCD2-6F61F0D3B611)]
library sbtsvClientLib
{
interface ITsSbResourceNotification;
};
However when I try to run it through MIDL
i get the following error
Microsoft (R) 32b/64b MIDL Compiler Version 8.00.0603 Copyright (c) Microsoft Corporation. All rights reserved. Processing .\sbtsvClientLib.idl sbtsvClientLib.idl Processing C:\Program Files (x86)\Windows Kits\8.1\include\um\oaidl.idl oaidl.idl Processing C:\Program Files (x86)\Windows Kits\8.1\include\um\objidl.idl objidl.idl Processing C:\Program Files (x86)\Windows Kits\8.1\include\um\unknwn.idl unknwn.idl Processing C:\Program Files (x86)\Windows Kits\8.1\include\shared\wtypes.idl wtypes.idl Processing C:\Program Files (x86)\Windows Kits\8.1\include\shared\wtypesbase.idl wtypesbase.idl Processing C:\Program Files (x86)\Windows Kits\8.1\include\shared\basetsd.h basetsd.h Processing C:\Program Files (x86)\Windows Kits\8.1\include\shared\guiddef.h guiddef.h Processing C:\Program Files (x86)\Windows Kits\8.1\include\um\SessdirPublicTypes.idl SessdirPublicTypes.idl Processing C:\Program Files (x86)\Windows Kits\8.1\include\um\oaidl.acf oaidl.acf midl\oleaut32.dll : error MIDL2020 : error generating type library : SetFuncAndParamNames failed : put_State (0x8002802C)
I am thinking I am going to be forced to write the classes and interfaces by hand, but I wanted to check to see if I was doing anything wrong that would allow this to work.
回答1:
There are two kinds of COM. The original kind, dating from the early nineties, targeted to make interop work in C or C++ and originated by the Office group at Microsoft. And the later kind, a subset of COM originally named OLE Automation. Developed by the Visual Basic team in the DevDiv group when they looked for an alternative for VBX, a 16-bit extension model for early versions of Visual Basic. Later renamed to ActiveX as a marketing term. Gaining lots of notoriety for being insecure, renamed back to plain COM.
Automation has been incredibly successful beyond the VB usage, any language runtime in Windows supports it. Significantly helped by it implementing a strict subset of COM that was easy to implement. And for supporting type libraries, a language-independent way to make a compiler aware of declarations.
That did not supplant the "old" COM, still very heavily used in Windows. Lots of apis are "old" style. The standard bat-signal for the non-Automation kind is seeing "cppquote" in the IDL file. Or interfaces that derive from IUnknown instead of IDispatch. Or methods using raw arrays instead of SAFEARRAY. Or structure types that comes from a Windows SDK header, the kind that only a C or C++ compiler can read.
Everything you see back in sbtsv.idl.
MIDL doesn't have any actual knowledge of the Automation restrictions, it just compiles the IDL and pig-headedly calls the ICreateTypeInfo interface methods in oleauto32. Which can easily object when the type library format doesn't support it. The error message sucks, it doesn't tell you exactly what declaration was at fault. Not unusual for MIDL, or Windows SDK tools in general, diagnostics are not its strength. DevDiv creates the friendly tools.
It doesn't otherwise takes a lot of guessing what declaration is at fault in sbtsv.idl. About all of them. You really do have to do this the hard way, writing the [ComImport] declarations yourself. Painful and error prone, do consider a C++/CLI wrapper instead.
来源:https://stackoverflow.com/questions/19716579/what-do-you-do-when-midl-cant-create-a-tlb