By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
449,369 Members | 1,550 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 449,369 IT Pros & Developers. It's quick & easy.

Fastest way to pass large array to and from COM

P: n/a
apm
Any and all:

Is there an efficient way to pass a large array from .NET to COM? Can
references (or pointer) be passed from COM to NET and NET to COM without the
object it refers to being copied?

Thanks in advance.

David
Nov 17 '05 #1
Share this Question
Share on Google+
5 Replies


P: n/a
David,

It depends on the interface. If you are using an Automation interface
and passing a SafeArray, then the runtime is going to have to create the
safearray and marshal the values into it.

However, if you are using COM interfaces that are not Automation based,
you can pass C-style arrays to the methods. Normally, the marshaller would
marshal the values over and cause a copy in most cases (where you are not
dealing with reference types). But, if you have an unsafe declaration that
takes a pointer to the type that contains the array, you can get the address
of the array and pass that.

You can ONLY do this with non-reference types though. Doing it on a
reference type would be pointless, since the marshaller has to marshal the
..NET reference to an unmanaged thunk that unmanaged code can work with.

Hope this helps.
--
- Nicholas Paldino [.NET/C# MVP]
- mv*@spam.guard.caspershouse.com

"apm" <Co*********@AdsorptionProcessModeling.com> wrote in message
news:LlEWe.11756$nq.8691@lakeread05...
Any and all:

Is there an efficient way to pass a large array from .NET to COM? Can
references (or pointer) be passed from COM to NET and NET to COM without
the object it refers to being copied?

Thanks in advance.

David

Nov 17 '05 #2

P: n/a
apm
You can ONLY do this with non-reference types though. Doing it on a
reference type would be pointless, since the marshaller has to marshal the
.NET reference to an unmanaged thunk that unmanaged code can work with.

Hope this helps.

Great help. Thank you. Will you offer further enlightenment on the subject
of what happens with reference types? This seems like it may be a bigger
problem.

If .NET would copy only once and use the copy in subsequent calls there
would be no problem. The problem I have is that a number of COM objects
were developed that support methods that may be called many thousands of
times before a run is complete. At one time the plan was to do future
development using .NET. Unfortunately the code took significantly (very,
very) longer to run when COM and .NET components were mixed.

David

--
- Nicholas Paldino [.NET/C# MVP]
- mv*@spam.guard.caspershouse.com

"apm" <Co*********@AdsorptionProcessModeling.com> wrote in message
news:LlEWe.11756$nq.8691@lakeread05...
Any and all:

Is there an efficient way to pass a large array from .NET to COM? Can
references (or pointer) be passed from COM to NET and NET to COM without
the object it refers to being copied?

Thanks in advance.

David


Nov 17 '05 #3

P: n/a
apm,

With reference types, the types have to be marshaled to the unmanaged
world. With an array of reference types, an unmanaged interface thunk is
created which can marshal the calls back to the managed realm.

You can optmize this though, if you have a good deal of processing to
do. What you can do is create an array of IntPtrs, one for each element in
your array of reference types. Then, you can cycle through your array,
passing the object to the static GetIUnknownForObject method on the Marshal
class, and placing the IntPtr in the array. Then, you can pass this array
to a method that accepts an array of interface pointers (not a SafeArray),
through unsafe code, and it should reduce the overhead of making multiple
calls.
--
- Nicholas Paldino [.NET/C# MVP]
- mv*@spam.guard.caspershouse.com

"apm" <Co*********@AdsorptionProcessModeling.com> wrote in message
news:b2FWe.11759$nq.4936@lakeread05...
You can ONLY do this with non-reference types though. Doing it on a
reference type would be pointless, since the marshaller has to marshal
the .NET reference to an unmanaged thunk that unmanaged code can work
with.

Hope this helps.


Great help. Thank you. Will you offer further enlightenment on the subject
of what happens with reference types? This seems like it may be a bigger
problem.

If .NET would copy only once and use the copy in subsequent calls there
would be no problem. The problem I have is that a number of COM objects
were developed that support methods that may be called many thousands of
times before a run is complete. At one time the plan was to do future
development using .NET. Unfortunately the code took significantly (very,
very) longer to run when COM and .NET components were mixed.

David

--
- Nicholas Paldino [.NET/C# MVP]
- mv*@spam.guard.caspershouse.com

"apm" <Co*********@AdsorptionProcessModeling.com> wrote in message
news:LlEWe.11756$nq.8691@lakeread05...
Any and all:

Is there an efficient way to pass a large array from .NET to COM? Can
references (or pointer) be passed from COM to NET and NET to COM without
the object it refers to being copied?

Thanks in advance.

David



Nov 17 '05 #4

P: n/a
You have to make a distinction between calling into COM and calling into
..NET.
When calling into COM from managed code, no marshaling is done when passing
an array, that is a reference is passed to the callee, no data is copied.
However, when calling into managed code from COM, the (Safe) array is copied
from unmanaged memory to managed memory.
The reason is simple, to be accesible by managed code, the array must
somehow be stored in the GC heap as an array of Type xxx, there is NO other
way to achieve this than by copying from unmanaged code to the managed heap.
When passed from managed code to COM, the managed array is wrapped in a
Safearray who's pvData field (a pointer) points to the adress of the first
array element, and this SafeArray is passed by reference.

Not sure what your problem is, copying a 2MB array for instance takes 1/10th
of the time needed to fill the array itself at the COM side (calling
SafeArrayPutElement).
Willy.

"apm" <Co*********@AdsorptionProcessModeling.com> wrote in message
news:LlEWe.11756$nq.8691@lakeread05...
Any and all:

Is there an efficient way to pass a large array from .NET to COM? Can
references (or pointer) be passed from COM to NET and NET to COM without
the object it refers to being copied?

Thanks in advance.

David

Nov 17 '05 #5

P: n/a
Hi David,

I see your problem. Of course there is the marshaling overhead when calling
into .NET and passing array's (SafeArray) from COM to the CLR. The major
overhead is due to the copying (memcpy) of the array to a managed array
reference type, the cost of marshaling back into COM is less important.

To give you an idea, marshaling a 20000 elem. Array of double's takes
~250µsec[*]. When using copy-in semantics (SomeMethod([In] arg...))

And ~300µsec when using copy in/out semantics ( SomeMethod([In, Out]
arg...))

You can reduce this call overhead to something like 20-30 µsec. when passing
a pointer to a C style array from COM to .NET in an unsafe context. Of
course this restrict you to use C++ as your COM components implementation
language, and because C style array's are not self describing, you have to
pass the size of the array as argument too.

For instance ...

unsafe public void SomeMethod([In, Out]double* dar, int al)

{ // use array indexed syntax to access elements

dar[n] = ...;

Now all depends on the service time (the time spent in the called method),
is this one is large compared to the marshaling time, you won't take much
advantage of pointer marshaling, however, if the call time is small and the
number of calls is high you can effectively reduce the call overhead by
using pointer marshaling.
Willy.
[*] PS the performance figures are those measured on a 3 Ghz P4 system
running XP SP2, you mileage may vary.

"apm" <Co*********@AdsorptionProcessModeling.com> wrote in message
news:b2FWe.11759$nq.4936@lakeread05...
You can ONLY do this with non-reference types though. Doing it on a
reference type would be pointless, since the marshaller has to marshal
the .NET reference to an unmanaged thunk that unmanaged code can work
with.

Hope this helps.


Great help. Thank you. Will you offer further enlightenment on the subject
of what happens with reference types? This seems like it may be a bigger
problem.

If .NET would copy only once and use the copy in subsequent calls there
would be no problem. The problem I have is that a number of COM objects
were developed that support methods that may be called many thousands of
times before a run is complete. At one time the plan was to do future
development using .NET. Unfortunately the code took significantly (very,
very) longer to run when COM and .NET components were mixed.

David

--
- Nicholas Paldino [.NET/C# MVP]
- mv*@spam.guard.caspershouse.com

"apm" <Co*********@AdsorptionProcessModeling.com> wrote in message
news:LlEWe.11756$nq.8691@lakeread05...
Any and all:

Is there an efficient way to pass a large array from .NET to COM? Can
references (or pointer) be passed from COM to NET and NET to COM without
the object it refers to being copied?

Thanks in advance.

David



Nov 17 '05 #6

This discussion thread is closed

Replies have been disabled for this discussion.