.net - COM 互操作 : indexed property signature issues

标签 .net c++ visual-studio interop c#-4.0

我正在开发一个项目,该项目是对一个相当大的经典 ASP 项目的 .NET 扩展,使用了大量 C++ COM 对象,这些对象一直存在于我们的代码库中。不幸的是,C++ 端有很多 hack-ish 代码,我担心我没有足够的经验来解决我遇到的问题。

简而言之,我可以实例化有问题的 COM 对象,Visual Studio 告诉我应该能够调用它的“方法”(在引号中,因为它们实际上作为参数化属性公开)。但是,我尝试调用的任何方法都会给我错误“索引属性‘CoreAspLib.IComUser.LoginUser’具有必须提供的非可选参数。”问题是,我使用的参数与经典 ASP 世界中使用的参数完全相同,甚至属性的 IntelliSense 帮助也告诉我我使用的是正确的参数集。例如,“LoginUser”属性的签名是“dynamic IComUser.get_LoginUser(string username, string password)”,我用两个字符串调用它,但我仍然收到“非可选参数”错误。

这里是一些相关代码 - 首先是我尝试进行方法调用的类。 CComUtils 是一个辅助类,它仅采用 COM 的 GUID 和对目标对象的引用,创建所需 COM 对象的实例,并将目标引用分配给新对象。

public static class CurrentUser
{
    public static void Authenticate(string userName, string password)
    {
        CoreAspLib.ComUser userObject = Cache.Request<CoreAspLib.ComUser>("UserComObject");

        if (userObject == null) {
            Guid userGuid = new Guid("BF748C0A-450D-4EAF-8C39-A36F6B455587");
            CComUtils.CreateCOMInstance(userGuid, ref userObject);
            Cache.Request("UserComObject", userObject);
        }

        var result = userObject.LoginUser(sUserName:"foo", sPassword:"bar");

        if (result.Failed) {
            throw (new System.Security.Authentication.InvalidCredentialException("Bad username or password".tr()));
        } else {
            FormsAuthentication.SetAuthCookie(userName, false);
        }
    }
}

这是来自 COM 对象源的实际方法签名:

STDMETHODIMP CComUser::get_LoginUser(BSTR bsUserName, BSTR bsPassword, IDispatch ** pResult)

这是来自 IDL 的接口(interface)定义:

[
    object,
    uuid(1F4D8A57-BDE1-4D47-A9BC-5F541A0ED184),
    dual,
    nonextensible,
    helpstring("IComUser Interface"),
    pointer_default(unique)
]
interface IComUser : IDispatch{
    [propget, id(1), helpstring("property LoginUser")] HRESULT LoginUser([in] BSTR sUserName, [in] BSTR sPassword, [out, retval] IDispatch ** pResult);
    [propget, id(2), helpstring("property m_nUserID")] HRESULT m_nUserID([out, retval] ULONG* pVal);
    [propget, id(3), helpstring("property m_nUserRightsMask")] HRESULT m_nUserRightsMask([out, retval] ULONG* pVal);
    [propget, id(4), helpstring("property SetPassword")] HRESULT SetPassword([in] BSTR sPassword, [in,optional] VARIANT nUserID, [out, retval] IDispatch ** pResult);
    [propget, id(6), helpstring("property VerifyLdapCredentials")] HRESULT VerifyLdapCredentials([in]BSTR sUserName, [in]BSTR sPassword, [in]BSTR sLdapServer,[in]ULONG nLdapPort,[in]BSTR sAuthorizeDn,[in]VARIANT_BOOL bSecure, [out, retval] IDispatch ** pResult);
    [propget, id(7), helpstring("property CreateUser")] HRESULT CreateUser([in] BSTR sUserName, [in] BSTR sPassword, [in]ULONG nUserRightsMask, [in] ULONG nAuthenticationType, [in] ULONG nHomeGroupID, [in] ULONG nLanguageID, [out, retval] IDispatch** pVal);
    [propget, id(8), helpstring("property m_nLanguageID")] HRESULT m_nLanguageID([out, retval] ULONG* pVal);
};

最后,这里是 coclass 定义:

[
    uuid(BF748C0A-450D-4EAF-8C39-A36F6B455587),
    helpstring("ComUser Class")
]
coclass ComUser
{
    [default] interface IComUser;
};

我该怎么办?

编辑:我应该提一下,我最初并没有使用命名参数;我只是尝试这样做,努力让错误消失。

最佳答案

嗯,您的代码建议您实际上使用 C# 4.0,因为您使用的是命名参数。该版本确实支持 COM 互操作方案中的索引属性。然而,索引器语法需要 [方括号]。不知道它是否仍然适用于多个参数,所有示例都只有一个。先试试这个:

 var result = userObject.LoginUser["foo", "bar"];

或者用以下方法解决问题:

 var result = userObject.get_LoginUser("foo", "bar");

请告诉我们您的发现,我很想知道是否支持具有多个参数的索引属性。

关于.net - COM 互操作 : indexed property signature issues,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3825727/

相关文章:

visual-studio - 在 .NET/Visual Studio 中定义 TRACE 常量

c# - HttpClient 不返回内容类型

.net - 如何解决此 SSRS 身份验证异常?

c++ - 关于 const 引用和临时对象的问题

c++ - 将 DWORD 从 HKCU 复制到 HKLM

c - 如何在 Windows 中编译 Python 3.7 的 C 扩展

c# - .NET 服务的 user.config 位于何处?

c# - 将通用列表转换为特定类型

c++ - 将包含多个数字的字符串转换为整数

macos - 将自定义项目模板添加到 Visual Studio Preview for Mac