1

Looking for a help with com server on C++.

Here is C# client code to invoke method:

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

This is how I call it:

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

I always get the COMException: HRESULT: 0x80020008 (DISP_E_BADVARTYPE)).

Here is C++ getting method:

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

And the .IDL file interface declaration:

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

Edit 1: This is correct code (without arrays):

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);

Thank you. Andrew

7
  • 1
    Question is a little unclear. In the second code block, you're passing in two arguments -- an object[] (containing two strings) and a string. And you say this works. Does the comment following that block mean that if you change the first argument to a string[], it fails? Commented Jul 14, 2017 at 19:12
  • Sorry, this doesn't work. I meant it worked until I began to try to pass array of string and haven't changed C++ method with "**". Commented Jul 14, 2017 at 19:17
  • 1
    So it works when you pass (object[], string), but not when you pass (string[], string)? Commented Jul 14, 2017 at 19:18
  • It worked, when I passed (string, string) and Im stuck with trying to pass (string[], string). To pass an array I added "**", but type mismatch... Sorry for my english, I know it may be hard to understand what am I trying to say Commented Jul 14, 2017 at 19:21
  • 1
    Please update your question with clear examples of what works and what doesn't. According to your post, it works when you pass (object[], string) (that's what your second code block does). Your post doesn't say anything about passing (string, string). Commented Jul 14, 2017 at 19:23

1 Answer 1

1

OP and I managed to get this working for him in an private discussion. This is a most likely an issue of what types the proxy/stub supports. I don't know all the details, but I do know that some of the out-of-the-box proxy/stubs that ship with COM have limited support for arrays.

Moreover, in my experience, when dealing with interop scenarios, it's almost always best to follow the rules for an OLE automation interface, as defined here. As indicated there, the only type of array that's supported is SAFEARRAY. This makes sense for automation, as SAFEARRAYs are the only standard array type that have enough metadata to describe their own contents and array shape.

Unfortunately, this documentation is either wrong regarding SAFEARRAYs or not informative enough. The only type of array I've ever gotten to work seamlessly between COM & .NET or COM & VBA is SAFEARRAY(VARIANT). Moreover, I have only ever gotten this working by passing it by reference (SAFEARRAY(VARIANT)*).

All that said, here's what worked for 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)
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.