0

My VB.NET script needs to use a library written in C#, specifically the Connect() method that has an out parameter that is a class. The VB.NET code calling the library method looks like this:

Dim devInfo As DeviceInfoType
myDevice.Connect(ChannelType.DEV_CHANNEL, 0, devInfo)

How the declaration looks like in the C# library:

// `ChannelType` is just an enum.
void Connect(ChannelType channel, UInt16 connectMode, out DeviceInfoType devInfo);

public class DeviceInfoType
{
    public GetIdType GetId { get; set; }
}

When I call myDevice.Connect() the computer waits a few seconds then an error is thrown (so I assume the device is being connected to, and once a connection is made the method tries to assign device info to the out parameter):

Object not set to instance of object

I can call other methods of myDevice just fine, so I assume it's something to do with the DeviceInfoType parameter. The author of the C# library told me that a C# user would have to call Connect() like this, but of course there is no out keywoard in VB.NET:

myDevice.Connect(ChannelType.DEV_CHANNEL, 0x00, out devInfo);

I also tried declaring devInfo like this, but still get the same error:

Dim devInfo As DeviceInfoType = Nothing
Dim devInfo As New DeviceInfoType
DBedrenko
  • 4,871
  • 4
  • 38
  • 73
  • 1
    Which line exactly throws that exception? Did you step through the code and found out which object is referred to by the error message? As you suggested, VB doesn't have an equivalent to the `out` keyword; it's not needed. If `myDevice.Connect(ChannelType.DEV_CHANNEL, 0x00, out devInfo);` works in a C# project, then `Dim devInfo As DeviceInfoType = Nothing : myDevice.Connect(ChannelType.DEV_CHANNEL, 0, devInfo)` should also work just fine in a VB project. If not, then there's probably something else going on that is not present in the question. – 41686d6564 stands w. Palestine Aug 30 '19 at 08:13
  • 1
    I would start by confirming that the `Connect()` method actually works when called in a C# assembly and then try to identify which object is `null` in VB when the exception occurs. That's, of course, assuming that it does work in C#. – 41686d6564 stands w. Palestine Aug 30 '19 at 08:15
  • @AhmedAbdelhameed Thank you for the suggestion. `myDevice.Connect()` is the line where the exception is thrown, I step until this function but of course cannot go inside it. After this call execution jumps to my `finally` block and then the error is shown. Before `Connect()` is called, `devInfo`'s value is `{Nothing}`. I may have to try using the library call in C#, maybe something is wrong with it? – DBedrenko Aug 30 '19 at 08:29
  • 1
    That's very likely. Based on the information you provided so far, nothing prevents the method to be called from VB if it works in C#. Here's a [quick example](https://i.imgur.com/ZNItJdO.png) which shows a close-enough C# method being called in a VB project. – 41686d6564 stands w. Palestine Aug 30 '19 at 08:47
  • What does the exception's stack trace tell you? – jmcilhinney Aug 30 '19 at 09:18
  • 1
    All `TryParse` methods (for example) are declared like this. If you have an exception, read what the exception is. *the computer waits a few seconds then an error is thrown (so I assume the device is being connected to...)*. I'ld assume the opposite. – Jimi Aug 30 '19 at 12:29
  • 1
    `out` is a C# feature rather than something defined in MSIL. It means that an additional attribute is placed on the argument (which you can also do in VB although in VB it doesn't have syntactic meaning), and the language enforces a requirement to set the value of the argument within the body of the routine. From the perspective of any other language, it's just another `ref` argument (or `ByRef` if you prefer). – Craig Aug 30 '19 at 13:00
  • 1
    VB should interoperate just fine with `out` arguments. Do beware that as with any `ByRef` argument, under certain circumstances it will pass by copy-in/copy-out instead of directly by reference i.e. changes occurring within the routine won't be visible by any other route (e.g. any sort of aliasing) until the routine ends. – Craig Aug 30 '19 at 13:02

1 Answers1

0

Turns out it was the library function that was doing something that caused the Object not set to instance of object exception. It happens because the 0x00 argument is not in the valid range; once I passed a value in the valid range there were no problems.

DBedrenko
  • 4,871
  • 4
  • 38
  • 73