简体   繁体   中英

How to declare Classic COM Interface IBindCtx in C#?

I am currently poking around C# and COM interfaces. COM Documentation in C# is sparse because C# came after COM (perhaps we at SO can fix). I discovered the C# compiler can give informative error messages . One can read the C# syntax version of the method signatures from the error messages and then add to your class. This worked for IAdviseSink but does not work for IBindCtx.

I am getting error for the last method RevokeObjectParam(string a) the syntax in C++ is HRESULT RevokeObjectParam( [in] LPOLESTR pszKey ); and LPOLESTR is a null terminated 2 byte based string so using [MarshalAs(UnmanagedType.LPWStr)] should work. But it doesn't, I get error messages

     * Class1.cs(25,14,25,40): error CS0539: 'IBindCtx.RevokeObjectParam' in explicit interface declaration is not a member of interface
     * Class1.cs(6,18,6,24): error CS0535: 'ComInterfacesInCSharp.Class1' does not implement interface member 'System.Runtime.InteropServices.ComTypes.IBindCtx.RevokeObjectParam(string)'

So how do I amend this method signature to fix please? Full code copyable into Visual Studio is below (create a Class Library project).

using System.Runtime.InteropServices.ComTypes;
using System.Runtime.InteropServices;

namespace ComInterfacesInCSharp
{
    public class Class1 : System.Runtime.InteropServices.ComTypes.IBindCtx 
    {
        void IBindCtx.RegisterObjectBound(object obj) { }
        void IBindCtx.RevokeObjectBound(object obj) { }
        void IBindCtx.ReleaseBoundObjects() { }
        void IBindCtx.SetBindOptions(ref System.Runtime.InteropServices.ComTypes.BIND_OPTS opts) { }
        void IBindCtx.GetBindOptions(ref System.Runtime.InteropServices.ComTypes.BIND_OPTS opts) { }
        void IBindCtx.GetRunningObjectTable(out System.Runtime.InteropServices.ComTypes.IRunningObjectTable tab) { }
        void IBindCtx.RegisterObjectParam(string s, object obj) { }
        void IBindCtx.GetObjectParam(string s, out object obj) { }
        void IBindCtx.EnumObjectParam(out System.Runtime.InteropServices.ComTypes.IEnumString enumString) { }

        /* Problem here https://msdn.microsoft.com/en-us/library/windows/desktop/ms693771(v=vs.85).aspx
         * C++ Syntax is 
         * HRESULT RevokeObjectParam( [in] LPOLESTR pszKey );
         * LPOLESTR is a null terminated 2 byte based string so UnmanagedType.LPWStr ought to work
         * 
         */
        //void IBindCtx.RevokeObjectParam(string a) { }
        void IBindCtx.RevokeObjectParam([MarshalAs(UnmanagedType.LPWStr)] string a) { }

        /*
         * Compile errors are
         * Class1.cs(25,14,25,40): error CS0539: 'IBindCtx.RevokeObjectParam' in explicit interface declaration is not a member of interface
         * Class1.cs(6,18,6,24): error CS0535: 'ComInterfacesInCSharp.Class1' does not implement interface member 'System.Runtime.InteropServices.ComTypes.IBindCtx.RevokeObjectParam(string)'
         */
    }
}

Incidentally, if you have a web resource detailing these interfaces in C# then that would be marvellous!

the link you have given is superb! It answers my question which was what was correct method signature. Now I have definitively from Microsoft.

While you can find many of the source code definitions from Microsoft's Reference Source site , it is not your only option for discovering the signature for a method defined in an assembly.

Learn to use Visual Studio's Object Browser . View Menu->Object Explorer (or press the F2 key).

In your particular case of implementing an interface, you can have Visual Studio auto implement the interface for you. Right-Click on the interface name ad select "Implement Interface".

在此处输入图片说明

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM