function should take a SAFEARRAY** parameter...
in the c++ function... So I'll stick to the SAFEARRAY** for the moment.
Thanks Brian, so I moved to unattributed code, and used the SAFEARRAY the
way you explain.
I now see, in c#, my funciton with a parameter of type 'ref System.Array'.
Looks good to me
But when I try to call the function with a System.Array that holds 2
elements, my ATL function get called, but with invalid values...
The SAFEARRAY I receive has a cdims of 44960, a cbElements of 0, null
data, a fFeatures of 33, a low bound of 10687108 ...
I suppose there is still something I don't do the right way, if you could
please have a look at my code...
thanks a lot for your help
Here is my code :
----------------------------------------------------
in the idl file :
[
object,
uuid(0622CD23-E28E-4DBD-9324-8EDE93EA54FA),
dual,
helpstring("IPs3Bridge Interface"),
pointer_default(unique)
]
interface IPs3Bridge : IDispatch {
[id(1), helpstring("method enumTargets")] HRESULT
enumTargets([in]SAFEARRAY(LONG)* _pArray);
};
[ version(1.0), uuid(1C1CEE99-298A-496F-A3A8-F9B67BB27AA0),
helpstring("ps3_bridge 1.0 Type Library") ]
library ps3_bridge
{
importlib("stdole2.tlb");
importlib("olepro32.dll");
[
version(1.0),
uuid(087CC8DF-7729-4DC9-BAE6-04ED5A6E3A98),
helpstring("Ps3Bridge Class")
]
coclass Ps3Bridge {
interface IPs3Bridge;
};
}
----------------------------------------------------
in the h file :
// IPs3Bridge
[
object,
uuid("0622CD23-E28E-4DBD-9324-8EDE93EA54FA"),
dual, helpstring("IPs3Bridge Interface"),
pointer_default(unique)
]
__interface IPs3Bridge : IDispatch
{
HRESULT enumTargets(SAFEARRAY* _pArray);
};
// Ps3Bridge
[
coclass,
threading("apartment"),
vi_progid("ps3_bridge.Ps3Bridge"),
progid("ps3_bridge.Ps3Bridge.1"),
version(1.0),
uuid("087CC8DF-7729-4DC9-BAE6-04ED5A6E3A98"),
helpstring("Ps3Bridge Class")
]
class ATL_NO_VTABLE Ps3Bridge :
public IPs3Bridge
{
public:
Ps3Bridge()
{
}
DECLARE_PROTECT_FINAL_CONSTRUCT()
HRESULT FinalConstruct();
void FinalRelease();
public:
STDMETHOD(enumTargets)(SAFEARRAY* _pArray);
};
----------------------------------------------------
in the cpp file :
STDMETHODIMP Ps3Bridge::enumTargets(SAFEARRAY* _pArray)
{
}
----------------------------------------------------
in the c# file :
ps3_bridge.Ps3BridgeClass bridge = new ps3_bridge.Ps3BridgeClass();
System.Array array = System.Array.CreateInstance(typeof(Int32),2);
int[] array2 = new int[2];
array2[0] = 5;
array2[1] = 10;
array2.CopyTo(array,0);
bridge.enumTargets(ref array);
"Brian Muth" <bmuth@mvps.org> a ?crit dans le message de news:
ulx3V0$ZGHA.504@TK2MSFTNGP03.phx.gbl...
"fabien bole-feysot" <fabien.bole-feysot_remove_me@ubisoft.com> wrote in
message news:uVEFZD7ZGHA.4424@TK2MSFTNGP02.phx.gbl...
hi
I have a COM Object MyComObject, and I would like to add a method that
take an array of long as a parameter.
The purpose of this method is to receive an already-allocated array of
long, and to fill it : void fillArray( long* first, int size) or
something like that.
This method is to be called from a c# code, so I would like it to be
seen as fillArray( long[] ) from my csharp module.
example of the way I would like to use it in c# :
long[] myArray = new long[10];
myComObject.fillArray(myArray);
How can I define this method in my COM object ? (All I need is the exact
declaration to put in the __interface MyComObject : IDispatch section,
and the corresponding C++ declaration for htis method
I tried to 'play' with SAFEARRAY, but I could not find a way to have it
understood by the compiler...
I can certainly provide you with a solution, but let me preface my answer
by stating that I do not work with attributed ATL. Visual Studio 2003 was
very buggy with attributed ATL, and I'm shy to use it in Visual Studio
2005 as well. So I will show you the unattributed solution. In fact, most
experts in this forum avoid attributed ATL as well; I suggest you do the
same.
Unfortunately for you, marshaling C# types of long[] is quite involved,
and I don't recommend it. You are much better off marshaling an Array
instead. You can use variables of type long[] if you like, but copy them
into an Array first.
Your IDL (unattributed ATL) can look like this:
[id(1), helpstring("method FillArray")] HRESULT FillArray([in, out]
SAFEARRAY(LONG) * MyArray);
Note it is not necessary to pass the length of the array as a separate
parameter. That information is embedded in the safearray itself.
To call this from C#, see below:
MyArrayLib.ArrObjClass c = new MyArrayLib.ArrObjClass();
Array arr = Array.CreateInstance (typeof (Int32), 2); // create a two
element array
arr.SetValue (0, 0); // set some values
arr.SetValue(2, 1);
c.FillArray(ref arr);
HTH,
Brian