2

I am converting a VB6 application to VB.net. The application uses an existing C library I can't change.

The Problem: I am expecting a value around -180 or 180. The times that I expect 180, it works. But when I expect -180, I get the value 4294967117. This seems like the C library is returning a 2's complement number, but I don't know how to treat it.

This is the VB6 code that works:

Dim tmp As Long

If GetVal(VAL_A1, tmp) = ERR_VAL_NA Then
    lblAngle(0).Caption = "na"
Else
    lblAngle(0).Caption = tmp
End If

This is the VB.net code that does not work:

    If GetVal(VAL_A1, tmp) = ERR_VAL_NA Then
        txtBoxPhaseAngle1.Text = "na"
    Else
        txtBoxPhaseAngle1.Text = Convert.ToDouble(tmp)
    End If

I have also tried:

 txtBoxPhaseAngle1.Text = Convert.ToInt32(tmp)

txtBoxPhaseAngle1.Text = tmp

EDIT :

How I declare the C function:

 Declare Function GetVal Lib "Z:\Devel\RelayAPI\Debug\RelayAPI.dll" (ByVal what As 
Integer, ByRef val As Long) As Byte

Snippets from the GetVal function in the C code:

BYTE __stdcall GetVal(WORD what, long *val){
    DWORD relaydate;
    BYTE tmpb;
    DWORD tmpd;
    long tmp;

    ...

        switch(what){

            case VAL_A1:
                tmpb=RelayAPI_Scaled;
                if(tmpd<6){
                    *val=(short)((WORD)mon[38]+((WORD)mon[39]<<8));
                }else{
                    *val=(short)((WORD)mon[32]+((WORD)mon[33]<<8));
                }
            break;

   break;
}
JuiCe
  • 4,132
  • 16
  • 68
  • 119
  • it might be how you get the value from the C lib; esp if this is a port from VB6 – Ňɏssa Pøngjǣrdenlarp Jul 24 '14 at 14:29
  • I will update my question with some more information on the function from the C library. I can change the C code if I absolutely have to, but it is really not ideal. – JuiCe Jul 24 '14 at 14:33
  • 1
    What does your dllimport function look like? You're right that the bits for -180 and 4294967117 look identical -- did you forget to change the dllimport declaration from `long` to `integer` when you converted from VB6? – pmcoltrane Jul 24 '14 at 14:34
  • Have you considered doing all of the bitwise math to just convert the number from twos compliment back to an integer value? Probably wouldn't be the cleanest code, but it might work. – Anthony Jul 24 '14 at 14:34
  • 1
    Maybe it's returning a 32bit number, not a 64bit. – the_lotus Jul 24 '14 at 14:37
  • @pmcoltrane I have updated my question with the dllimport declaration. – JuiCe Jul 24 '14 at 14:39
  • 1
    @JuiCe as `the_lotus` said, the function is probably returning a 32-bit value. In VB6, `Long` is 32-bits, but a VB.NET `Long` is 64-bits. The C function uses `long`, which according to spec is guaranteed to be "at least 32-bits". Try changing your dllimport declaration to `ByRef val As Integer` and see if it works. – pmcoltrane Jul 24 '14 at 14:43
  • Thank you guys, changing my dllimport declaration to use an `Integer` solved my problem. If either @the_lotus or @pmcoltrane would put that as an answer I will accept it. – JuiCe Jul 24 '14 at 14:48

1 Answers1

2

When upgrading from VB6, you need to be aware that some data types have changed. In VB6, an Integer is 16-bits, and a Long is 32-bits. In VB.NET, though, an Integer is 32-bits and a Long is 64-bits.

In the C function, you have long *val, and a C long is "at least 32-bits" according to spec, so presumably your C-function is returning a 32-bit integer. However, VB.NET now believes that it's a Long (64-bit) value, and interprets it as such -- 4294967117 instead of -180.

If you change your VB.NET declaration of the val parameter to ByRef val As Integer, you will probably see the correct return value.

pmcoltrane
  • 3,052
  • 1
  • 24
  • 30