Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsFree MagazinesWhite PapersSubmit Content
Discussion GroupsASP.NETWindows FormsLanguages.NET FrameworkVisual Studio.NET
Articles.NET FrameworkASP.NETToolsWindows Forms
.NET DirectoryOpen Source ProjectsUser GroupsWeb Resources
Related Topics
Visual Basic 6SQL ServerMS AccessOther DB ProductsMS Server ProductsMore Topics ...

.NET Forum / .NET Framework / Interop / August 2004

Tip: Looking for answers? Try searching our database.

OLEAutomation Interop with object []

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
Phil Wilson - 26 Aug 2004 22:16 GMT
There doesn't seem to be an obvious (to me anyway!) way to have an interface
in .NET that passes an object [] such that it can be used by (say) VBScript.
In other words, given a method:

[ComVisible(true), GuidAttribute("66F12379-0C8F---------- etc")]
[ClassInterface(ClassInterfaceType.AutoDispatch)]
[ProgId("blah.blah")]
public class Class1: IMyInterface
{
 ..
 public void Connect(object [] initializeData )

}

What is required (MarshalAs or whatever) is that this kind of script works:

set obj = createobject("blah.blah")
dim parm(2)
parm (1) = "this"
parm(2)="that"

obj.Connect  parm

The error is pretty consistent at 0x800A0005 Invalid procedure call or
argument: 'obj.Connect'

Help Welcome, thanks.
Signature

Phil Wilson [MVP Windows Installer]
----

Robert Jordan - 27 Aug 2004 09:13 GMT
Hi Phil,

> There doesn't seem to be an obvious (to me anyway!) way to have an interface
> in .NET that passes an object [] such that it can be used by (say) VBScript.
[quoted text clipped - 11 lines]
>
> What is required (MarshalAs or whatever) is that this kind of script works:

You don't need any special marschal instructions, because
the runtime already has a default marschaler for "object[]".

However, VBScript is not able to pass the expected SAFEARRAY
by value. It simply doesn't support that. You have to change
the managed signature from

   public void Connect(object [] initializeData )

to

   public void Connect(ref object [] initializeData )

> set obj = createobject("blah.blah")
> dim parm(2)
[quoted text clipped - 5 lines]
> The error is pretty consistent at 0x800A0005 Invalid procedure call or
> argument: 'obj.Connect'

Rob
Willy Denoyette [MVP] - 27 Aug 2004 09:59 GMT
> Hi Phil,

> However, VBScript is not able to pass the expected SAFEARRAY
> by value.

Sure it has just put the arg between parens like this:

obj.Connect  (parm)

when calling a function use double parens:
r = obj.Connect((param))

Following calls a method with two params one byval another byref.

r = obj.Method((p1), p2)

Willy.
Robert Jordan - 27 Aug 2004 10:43 GMT
>>However, VBScript is not able to pass the expected SAFEARRAY
>>by value.
[quoted text clipped - 9 lines]
>
> r = obj.Method((p1), p2)

Thanks for the syntax. Does the interop now work?

Rob
Phil Wilson - 27 Aug 2004 19:21 GMT
It's not a syntax issue - that's just me doing sloppy cut&paste - the issue
is the 0x800A0005 Invalid procedure call or
argument: 'obj.Connect'. I tried a ref on the object [], still doesn't work.
This is the entire class library and VBScript. I just have a nagging feeling
it should work with the right incantation somewhere.

using System;
using System.Runtime.InteropServices;
using System.Windows.Forms;
namespace TestCL
{
[ComVisible(true), GuidAttribute("EBFCDECB-CF01-467c-A15E-D57ABE4E3C6F")]
[ClassInterface(ClassInterfaceType.AutoDispatch)]
[ProgId("blah.blah")]
public class Class1
{
public void Connect(ref object [] initializeData )
{
MessageBox.Show (initializeData[0].ToString());
}
}
}

' VBScript source code
set obj = createobject("blah.blah")
dim parm(2)
parm (1) = "this"
parm(2)="that"
obj.Connect parm
Signature

Phil Wilson
[MVP Windows Installer]

> >>However, VBScript is not able to pass the expected SAFEARRAY
> >>by value.
[quoted text clipped - 13 lines]
>
> Rob
Willy Denoyette [MVP] - 27 Aug 2004 22:13 GMT
Yes it is a syntax issue, try and take a look at following small sample:

1. CS file inprocserver.cs

// Compile with csc /t:library inprocserver.cs
// and use Regasm /codebase inprocserver.dll to register
using System.Runtime.InteropServices;
using System;

// interface
[InterfaceType(ComInterfaceType.InterfaceIsDual)]
[Guid("1ab6f6ea-83b5-4b16-934b-fb98d9af8e0a")]
public interface IDotNetInterface
{
int WriteEx(ref object[] aParam1, string s); }
// class
[ClassInterface(ClassInterfaceType.None)]
[ProgId("Test.DotNetIf")]
public class DotNetInterface : IDotNetInterface
{
public DotNetInterface() {}
public int WriteEx(ref object[] aParam1, string s)
{
 Console.WriteLine("Length: {0}", aParam1.Length);
 int i = 0;
 foreach(byte b in aParam1)
 {
  Console.WriteLine(b);
  aParam1[i] = (byte)aParam1[i] + 1;    // change each element in the array
  i++;
 }
 return aParam1.Length
}
}

And the VBScript file:

Dim arr(2)
' pass byte array just for the fun
arr(0) = CByte(10)
arr(1) = CByte(20)
arr(2) = CByte(30)
set o = CreateObject("Test.DotNetIf")
r = o.WriteEx ((arr), "test")
' uncomment next to see how it fails
' r = o.WriteEx (arr, "test")
for each b in arr
WScript.Echo "Array elem  = " & b
next

Feel free to ask more questions.

Willy.

> It's not a syntax issue - that's just me doing sloppy cut&paste - the
> issue
[quoted text clipped - 45 lines]
>>
>> Rob
Phil Wilson - 28 Aug 2004 00:29 GMT
Ok, got it, many thanks. Those double parentheses are what I hadn't noticed.
Signature

Phil Wilson
[MVP Windows Installer]

> Yes it is a syntax issue, try and take a look at following small sample:
>
[quoted text clipped - 99 lines]
> >>
> >> Rob
Willy Denoyette [MVP] - 28 Aug 2004 21:54 GMT
Phil,

When using VBScript as client it's better to consider all arguments passes
as VARIANT's in C#. Note that VBScript considers all variables as variants,
but internaly the scripting engine uses the real variant types, so you need
to declare a variant to be passed as arg. Here's a sample.

public int ModArray(ref object aParam1)
{
 object[] arr = aParam1 as object[]; // aParam1 is a now a VARIANT wrapping
a SAFEARRAY of VARIANT's
 int i = 0;
 foreach(object b in arr){        // for each object (VARIANT) in arr
  Console.WriteLine(b);
  arr[i] =(byte)( (int)arr[i] - 1);    // change the values
  i++;
 }
 return (aParam1 as Array).Length;
}

Dim arr(2)
' pass byte array just for the fun
arr(0) = CByte(10)
arr(1) = CByte(20)
arr(2) = CByte(30)
set o = CreateObject("Test.DotNetIf")
dim var    'declare variant variable
var = arr    'set variant variable to array
r = o.ModArray(var)    'pass variant not the array
for each b in var
WScript.Echo "Array elem  = " & b
next

Willy.

> Ok, got it, many thanks. Those double parentheses are what I hadn't
> noticed.
[quoted text clipped - 103 lines]
>> >>
>> >> Rob

Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.