0

I'm editing a legacy program in VB when most of my computer programming experience is in C#. The program in question compiles fine but when running I get to a certain function call to a DLL file and I get the following:

System.InvalidCastException: 'Unable to cast object of type 'System.Int32[*]' to type 'System.Int32[]'.'

The arguments that are causing the issue are Dim'd As Integer. The function wants the arguments ByRef As Array. However, even when redefining the arguments As Array it says:

'Unable to cast object of type 'System.Int32[*]' to type 'System.Array'.'

EDIT

To try and give "minimal, complete, and verifiable example" as suggested by ItsPete here is some code.

I am using DA 1 OPC Wrapper DLL. This project is something I had to add a few part numbers to, not something I wrote from scratch.

Dim ConnectedOPCServer As New OPCAutomation.OPCServer
Public OPCItemCollection As OPCAutomation.OPCItems
Public gConnectedGroup As OPCAutomation.OPCGroup
Dim ConnectedServerGroups As OPCAutomation.OPCGroups
Dim ItemServerHandles() As Integer
Dim ItemServerErrors() As Integer
Dim OPCItemIDs() As String
ConnectedOPCServer = New OPCAutomation.OPCServer
ConnectedOPCServer.Connect("Kepware.KEPServerEX.V5")
ConnectedServerGroups = ConnectedOPCServer.OPCGroups
gConnectedGroup = ConnectedServerGroups.Add("Group1")
gConnectedGroup.UpdateRate = 200
gConnectedGroup.IsSubscribed = True
Call Add_OPC_Items() 'This adds tags to the OPC collection by assigning elements of the OPCItemIDs array to tag names
OPCItemCollection = gConnectedGroup.OPCItems
OPCItemCollection.DefaultIsActive = True
OPCItemCollection.AddItems(ItemCount, OPCItemIDs, ClientHandles, ItemServerHandles, ItemServerErrors)

I think that is all that is needed. Like I said...I just expected to add a few part numbers to a drop down selection and not have to dig neck deep into debugging this so I'm kinda out of my depth.

Hans Passant that might be promising. But that looks like it is for C# or C++ and not VB. I dont know how there are many duplicates...searching for Int32[*] didn't return much between Google and Stackoverflow's own search.

And holy crap Jimi that is like a day of reading.

Kevin S
  • 11
  • 1
  • Could you please edit your question to provide a [Minimal, Complete, and Verifiable Example](https://stackoverflow.com/help/mcve) so we can see what you've tried. – ItsPete Jan 09 '20 at 22:35
  • 1
    Many duplicates, try [this one](https://stackoverflow.com/a/23196890/17034). – Hans Passant Jan 09 '20 at 22:39
  • See also this article: [Understanding Classic COM Interoperability With .NET Applications](https://www.codeproject.com/Articles/990/Understanding-Classic-COM-Interoperability-With-NE), more specifically, the *Using COM Collections from .NET Applications* section. – Jimi Jan 09 '20 at 22:51
  • 1
    Updated main post with responses. Hopefully things will make more sense after a night of sleep. – Kevin S Jan 09 '20 at 23:27
  • ... that's why a added *more specifically...*. It's a *compendium* to what's described in Hans Passant's notes (it's a good reading, overall, anyway). There's not much of a difference if you're coding in C# or VB.Net when it comes to COM Interop. – Jimi Jan 10 '20 at 01:03
  • I don't remember if the interop marshaller will adjust array characteristics or not when it marshals the ref back, but you can create a array of type `System.Int32[*]` with `Dim ItemServerHandles As Array = Array.CreateInstance(GetType(Int32), {2}, {1})`. This create an array with Length = 2 and a lower bound of 1. – TnTinMn Jan 10 '20 at 03:58
  • Hans's cited answer describes what happens in the .NET runtime and thus is not specific to VB or C# in that respect. It may be easier to access elements from VB; it's been a while since I rebelled against the misdesign of forcing a 0 lower bound in .NET, so I don't remember what happened when I was making one-bounded arrays using `Array.CreateInstance`. TnTinMn's code is how you create a non-vector rank-1 `System.Array`. – Craig Jan 10 '20 at 14:07

0 Answers0