473,325 Members | 2,308 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,325 software developers and data experts.

Passing SAFEARRAY of Bytes from VBScript to Managed COM object (C#

Attempting to pass a VBScript Array of Bytes to a C# Managed COM object has
resulted in some very undesirable and strange behavior. When definining a
method in my C# COM class as "void Write(byte[] bBytes)" or "void
Write(byte[] bBytes, int nLen)" or "int Write(byte[] bBytes, int
nLen)"VBScript returns a "Invalid procedure call or argument" exception.
However when I define the method as "int Write(byte[] bBytes)" it works just
fine. Unfortunately the method definition that works is not the one I need.
Regardless of whether one works or one doesn't work, they should all work.
Does anyone know why the CCW can't handle the method definition, and why it
is behaving in such a flakey manner?

Things I have tried to make it work:
- I have used the appropriate MarshalAs attribute in front of the byte[]
array.
- I have used the [ClassInterface(ClassInterfaceType.None)] attribute with
an explicit interface to make the tlbexp tool explicitly define the interface
methods.
Jul 21 '05 #1
2 13373
Complex types as arrays are expected to be VARIANT's when calling into COM
through COM interop.
So you have to declare them as Object (or ref Object for [in,out]) in
CSharp.

Here's a sample that illustrates this...

// CS file
using System.Runtime.InteropServices;
using System;

// interface
[InterfaceType(ComInterfaceType.InterfaceIsDual)]
[Guid("1ab6f6ea-83b5-4b16-934b-fb82d9af8e0a")]
public interface IDotNetInterface
{
int Write( Object aParam1); //[in]VARIANT
}

// class
[ClassInterface(ClassInterfaceType.None)]
[ProgId("Test.DotNetIf")]
public class DotNetInterface : IDotNetInterface
{
public DotNetInterface() {}
public int Write( Object aParam1)
{
foreach(byte b in aParam1 as Array)
Console.WriteLine(b);
return (aParam1 as Array).Length; // Return Array.Length (will be
marshalled as a VARIANT containing an int type)
}
}

'VBS file
On Error Resume Next
Dim o
Dim ar 'Variant
Dim arr(2) 'Array 3 elements
arr(0) = CByte(1) 'add 1 as byte value in element 0
arr(1) = CByte(2)
arr(2) = CByte(3)
ar = arr 'set ar to array
set o = CreateObject("Test.DotNetIf")
r = o.Write (ar) 'pass Variant containing an array of bytes to callee
if Err.Number <> 0 then
Wscript.Echo "Failure :" & Err.Description
else
Wscript.Echo r
end if

Willy.
"Ken Layton" <Ke*******@discussions.microsoft.com> wrote in message
news:E9**********************************@microsof t.com...
Attempting to pass a VBScript Array of Bytes to a C# Managed COM object
has
resulted in some very undesirable and strange behavior. When definining a
method in my C# COM class as "void Write(byte[] bBytes)" or "void
Write(byte[] bBytes, int nLen)" or "int Write(byte[] bBytes, int
nLen)"VBScript returns a "Invalid procedure call or argument" exception.
However when I define the method as "int Write(byte[] bBytes)" it works
just
fine. Unfortunately the method definition that works is not the one I
need.
Regardless of whether one works or one doesn't work, they should all work.
Does anyone know why the CCW can't handle the method definition, and why
it
is behaving in such a flakey manner?

Things I have tried to make it work:
- I have used the appropriate MarshalAs attribute in front of the byte[]
array.
- I have used the [ClassInterface(ClassInterfaceType.None)] attribute with
an explicit interface to make the tlbexp tool explicitly define the
interface
methods.

Jul 21 '05 #2
Note that you can also pass them byval as SAFEARRAY(VARIANT) (Variant array)

//CS file
public interface IDotNetInterface
{
int Write(object[] aParam1);
}
....

public int Write( object[] aParam1) // Object [] == SAFEARRAY(Variant)
{
foreach(byte b in aParam1) // Variant encapsulates a byte
Console.WriteLine(b);
return aParam1.Length;
}

'SCRIPT
Dim ar
Dim arr(2)
arr(0) = CByte(1)
arr(1) = CByte(2)
arr(2) = CByte(3)
ar = arr
WScript.Echo TypeName(arr)
set o = CreateObject("Test.DotNetIf")
r = o.Write ((ar)) 'Pass ar byval
'OR
r = o.Write ((arr)) 'Pass arr byval

Willy.

"Ken Layton" <Ke*******@discussions.microsoft.com> wrote in message
news:E9**********************************@microsof t.com...
Attempting to pass a VBScript Array of Bytes to a C# Managed COM object
has
resulted in some very undesirable and strange behavior. When definining a
method in my C# COM class as "void Write(byte[] bBytes)" or "void
Write(byte[] bBytes, int nLen)" or "int Write(byte[] bBytes, int
nLen)"VBScript returns a "Invalid procedure call or argument" exception.
However when I define the method as "int Write(byte[] bBytes)" it works
just
fine. Unfortunately the method definition that works is not the one I
need.
Regardless of whether one works or one doesn't work, they should all work.
Does anyone know why the CCW can't handle the method definition, and why
it
is behaving in such a flakey manner?

Things I have tried to make it work:
- I have used the appropriate MarshalAs attribute in front of the byte[]
array.
- I have used the [ClassInterface(ClassInterfaceType.None)] attribute with
an explicit interface to make the tlbexp tool explicitly define the
interface
methods.

Jul 21 '05 #3

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

1
by: lolomgwtf | last post by:
I have a managed C++ method that wraps unmanaged code and creates a managed object holding data retrieved form an unmanged one. I want create an instance of this managed class in C#, pass it to...
4
by: Roland Moschel | last post by:
Hi there ! I have some Problems to get a SafeArray out of a COM Server written in (Unmanaged) C++. From (unmanaged) Visual Basic , everything is ok , but unfortunately in C# I get an...
2
by: lolomgwtf | last post by:
I have a managed C++ method that wraps unmanaged code and creates a managed object holding data retrieved form an unmanged one. I want create an instance of this managed class in C#, pass it to...
2
by: Ken Layton | last post by:
Attempting to pass a VBScript Array of Bytes to a C# Managed COM object has resulted in some very undesirable and strange behavior. When definining a method in my C# COM class as "void Write(byte...
7
by: Tim | last post by:
When there is a need to pass some dynamic information between 2 managed assemblies, the "Dictionary object" in Generic form can be used as a method parameter to pass the information. The...
5
by: Maxim | last post by:
Hi all, I'm calling a COM Interface method that returnes SafeArray wrapped into variant. Is it possible to convert it to managed array? Because working with SAFEARRAY directly is a bit...
17
by: =?Utf-8?B?U2hhcm9u?= | last post by:
Hi Gurus, I need to transfer a jagged array of byte by reference to unmanaged function, The unmanaged code should changed the values of the array, and when the unmanaged function returns I need...
0
by: eitanyan | last post by:
I am trying to create a Java to .Net interop and the way I am doing it is by creating a C# com object and a native unmanaged c++ dll that uses JNIEnv of java. the java is loading the native c++ dll...
0
skeptics
by: skeptics | last post by:
Trying to pass a SafeArray that i get form Request.BinaryRead Method in classic asp to a c# com interop component. In this thread i found a solution to pass and cast a normal asp safearray in to a c#...
0
by: DolphinDB | last post by:
Tired of spending countless mintues downsampling your data? Look no further! In this article, you’ll learn how to efficiently downsample 6.48 billion high-frequency records to 61 million...
0
by: ryjfgjl | last post by:
ExcelToDatabase: batch import excel into database automatically...
0
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
0
by: Vimpel783 | last post by:
Hello! Guys, I found this code on the Internet, but I need to modify it a little. It works well, the problem is this: Data is sent from only one cell, in this case B5, but it is necessary that data...
0
by: jfyes | last post by:
As a hardware engineer, after seeing that CEIWEI recently released a new tool for Modbus RTU Over TCP/UDP filtering and monitoring, I actively went to its official website to take a look. It turned...
1
by: PapaRatzi | last post by:
Hello, I am teaching myself MS Access forms design and Visual Basic. I've created a table to capture a list of Top 30 singles and forms to capture new entries. The final step is a form (unbound)...
0
by: af34tf | last post by:
Hi Guys, I have a domain whose name is BytesLimited.com, and I want to sell it. Does anyone know about platforms that allow me to list my domain in auction for free. Thank you
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome former...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.