在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);
谢谢。 安德鲁
答案 0 :(得分:1)
此外,根据我的经验,在处理互操作方案时,几乎总是最好遵循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)