从C#客户端调用C ++ COM服务器功能

时间:2017-07-14 18:41:50

标签: arrays string com client-server idl

在C ++上寻找com服务器的帮助。

以下是调用方法的C#客户端代码:

public static object ComInvoke(string method, params object[] args)
{
    return _comObj.GetType().InvokeMember(method, BindingFlags.InvokeMethod, Type.DefaultBinder, _comObj, args);
}

这就是我所说的:

string[] result = (string[])ExplorerCore.ComInvoke("CopyFiles", new object[]{"arg1_1", "arg1_2"}, "arg2");

我总是得到COMException:HRESULT:0x80020008(DISP_E_BADVARTYPE))。

这是C ++获取方法:

STDMETHODIMP CopyFiles(BSTR ** src, BSTR dest, BSTR ** result);

.IDL文件接口声明:

HRESULT CopyFiles([in, string] BSTR ** src, [in, string] BSTR dest, [out, retval] BSTR ** test);

编辑1: 这是正确的代码(没有数组):

C#:

string[] result = (string[])ExplorerCore.ComInvoke("CopyFiles", "arg1", "arg2");

C ++

STDMETHODIMP CopyFiles(BSTR src, BSTR dest, BSTR* result);

IDL:

HRESULT CopyFiles([in, string] BSTR src, [in, string] BSTR dest, [out, retval] BSTR* test);

谢谢。 安德鲁

1 个答案:

答案 0 :(得分:1)

OP和我设法让他在私人讨论中为他工作。这很可能是代理/存根支持的类型的问题。我不知道所有的细节,但我知道COM附带的一些开箱即用的代理/存根对数组的支持有限。

此外,根据我的经验,在处理互操作方案时,几乎总是最好遵循OLE自动化接口的规则,如定义here。如此处所示,支持的唯一类型的数组是SAFEARRAY。这对于自动化是有意义的,因为SAFEARRAY是唯一具有足够元数据来描述其自身内容和数组形状的标准数组类型。

不幸的是,关于SAFEARRAY或者没有足够的信息,这个文档是错误的。我唯一能够在COM和COM之间无缝工作的阵列类型.NET或COM& VBA是SAFEARRAY(VARIANT)。而且,我只是通过引用(SAFEARRAY(VARIANT)*)传递它。

所有这一切,这就是OP的作用:

IDL:

HRESULT CopyFiles([in] SAFEARRAY(VARIANT)* src, [in] BSTR dest, [out, retval] SAFEARRAY(VARIANT)** test);

C ++:

STDMETHODIMP CopyFiles(LPSAFEARRAY src, BSTR dest, LPSAFEARRAY* result)