com interop - calling unmanged C++ method with an array, of a class, via COM from C#

I posted a question regarding this previously, but the suggestions didn't help, so I'm trying again.

I'll include more code this time.

I have existing unmanaged C++ code. There is a class that I am using. I can access it via COM. For methods that just take primative data types everything works find.For methods of the class that take arrays things don't work so well because the C# code that is generated expects a ref to a single value, not an array.

The problem is that the generated C# code only wants a reference, not an actual array.

This is what I am doing:
1. build the C++ class in one solution
2. goto my C# solution, reference the C++ dll, and make it isolated COM reference
3 instantiate the COM class
4. try and pass an array to a method

#4 fails because I need to pass an array, but on a ref

Below is some of the code.

Any help would be awesome,
thanks

########################################################################
// ComDomo.h
[
object,
uuid("2158751B-896E-461d-9012-EF1680BE0628"),
dual,
helpstring("IMath Interface")
]
__interface IDemo : IDispatch
{
[id(1)] HRESULT Add([in] LONG val1, [in] LONG val2, [out, retval] LONG* result);
[id(2), helpstring("method Writer")] HRESULT Writer([in, size_is(len)] int* pData, [in] int len);
};

[
coclass,
threading(apartment),
version(1.0),
uuid("0CB36265-44F8-47E4-9CAD-FFFBCB0C7B71"),
helpstring("ComDemo Class")
]
class ATL_NO_VTABLE ComDemo : public IDemo
{
public:
ComDemo(){ }

DECLARE_PROTECT_FINAL_CONSTRUCT()

HRESULT FinalConstruct()
{
return S_OK;
}

void FinalRelease() { }

public:
STDMETHOD(Writer)(int stuff[], int len);
STDMETHOD(Add)(LONG val1, LONG val2, LONG* result);
};
########################################################################

########################################################################
//ComDemo.cpp
#include "stdafx.h"
#include "ComDemo.h"
#include <iostream>

using namespace std;

STDMETHODIMP ComDemo::Writer(int* stuff, int len)
{
std::cout << "ComDemo::Writer(int* stuff, int len)" << std::endl;

for(int i=0; i<len; i++)
std::cout << "input was " << stuffIdea << std::endl;

return S_OK;
}

STDMETHODIMP ComDemo::Add(LONG val1, LONG val2, LONG* result)
{
*result = val1 + val2;
return S_OK;
}
########################################################################

########################################################################
// a C# snippet from the project that calls this:

using System;
using System.Runtime.InteropServices;

namespace csharp_calls_com
{
class Program
{
static void Main(string[] args)
{
int[] arrayOfInts = new int[]{10,9,8,7,6};

ComServer.ComDemo cd = new ComServer.ComDemo();

//
// THIS IS WHAT IS ONLY TAKING A REF, NOT AN ARRAY
//
cd.Writer(ref arrayOfInts[0], arrayOfInts.Length);

Console.ReadKey();
}
}
}
########################################################################

[3365 byte] By [Boise83716] at [2007-12-24]
# 1
Is there a different forum I should use for this?

Does anyone know any good blogs of MS Devs that do COM interop?

It's as if no one has ever passed an array from managed code to a method of a class via COM.

Has anyone done this before?

Boise83716 at 2007-10-8 > top of Msdn Tech,Visual C#,Visual C# Language...
# 2

I think, that marshaling is all you need. Try following code snippet:

using System;
using System.Runtime.InteropServices;

namespace csharp_calls_com
{
class Program
{
static void Main(string[] args)
{
int[]arrayOfInts = new int[]{10,9,8,7,6};

int size = Marshal.SizeOf(arrayOfInts[0]) * arrayOfInts.Length;

IntPtr pnt = Marshal.AllocHGlobal(size);

ComServer.ComDemo cd = new ComServer.ComDemo();

try

{

Marshal.Copy(arrayOfInts, pnt, 0, arrayOfInts.Length);

cd.Writer(pnt, arrayOfInts.Length); // maybe you need cast pnt to int [] here?
}

finally

{

Marshal.FreeHGlobal(pnt);

}

Console.ReadKey();
}
}
}

Peca55 at 2007-10-8 > top of Msdn Tech,Visual C#,Visual C# Language...
# 3
This won't compile, because the the Method "Writer" wants a "ref int" as it's first element.

the call to Marshal.Copy had a reversed array also, this fixes it:
Marshal.Copy(arrayOfInts, 0, pnt, arrayOfInts.Length);

Boise83716 at 2007-10-8 > top of Msdn Tech,Visual C#,Visual C# Language...
# 4

You have in ComDemo.cpp

STDMETHOD(Writer)(int stuff[], int len);

so I think the first parameter is InPtrto Int[] array., sorry for that and array reversal (:

Peca55 at 2007-10-8 > top of Msdn Tech,Visual C#,Visual C# Language...