Author Topic: Getting error type mismatch when compiling  (Read 2756 times)

0 Members and 1 Guest are viewing this topic.

Karen Zibowski

  • Guest
Getting error type mismatch when compiling
« on: March 07, 2018, 07:49:48 PM »
I have the following program to get the HDD serial numbers using the GetVolumeInformationA
API function

Code: OxygenBasic
  1. $ filename "GetHDDSerial_64.exe"
  2. use rtl64
  3.  
  4.  
  5.  
  6.  
  7. include     "RTL64.inc"
  8. include     "minwin.inc"
  9.  
  10. DECLARE FUNCTION GetVolumeInformation Lib "kernel32.dll" Alias
  11.         "GetVolumeInformationA" (ByVal lpRootPathName As String, ByVal lpVolumeNameBuffer As String,
  12.                   ByVal nVolumeNameSize As Long, lpVolumeSerialNumber As Long,
  13.         lpMaximumComponentLength As Long, lpFileSystemFlags As Long, ByVal
  14.         lpFileSystemNameBuffer As String, ByVal nFileSystemNameSize As Long) As Long
  15.  
  16.  
  17. '==========================================
  18. ' Obtain the Hard Drive Serial number
  19. FUNCTION DriveSerialNumber(Drive AS STRING) AS STRING
  20. LOCAL HWord AS DWORD
  21. LOCAL LWord AS DWORD
  22. LOCAL Volname AS  STRING
  23. LOCAL VolBuffer AS  STRING  
  24. LOCAL lpVolumeSerialNumber AS LONG
  25. LOCAL lpMaximumComponentLength AS LONG
  26. LOCAL lpFileSystemFlags AS LONG
  27. LOCAL FileSysBuffer AS STRING
  28.  
  29. IF GetVolumeInformation (BYCOPY Drive, VolBuffer, SIZEOF(VolBuffer), lpVolumeSerialNumber , lpMaximumComponentLength,
  30. lpFileSystemFlags , FilesysBuffer, SIZEOF(FilesysBuffer)) <> 0 THEN
  31.     HWord = HIWRD(lpVolumeSerialNumber)
  32.     LWord = LOWRD(lpVolumeSerialNumber)
  33.     FUNCTION = RIGHT$("0000000"+HEX$(HWord), 4)  + RIGHT$("0000000"+HEX$(LWord), 4)
  34. ELSE
  35.     FUNCTION = "Cannot Read Drive.."
  36. END IF
  37.  
  38. END FUNCTION
  39.  
  40.  
  41.  
  42. '===================================
  43.    DIM AS STRING  Dsn , dDrive
  44.      dDrive = "c:\"
  45.      Dsn = DriveSerialNumber(dDrive)
  46.      print  Dsn
  47.  
  48.  
  49.  
  50.  
  51.  
  52.  


The type mismatch lies at line 10
DECLARE FUNCTION GetVolumeInformation Lib .....

How to resolve this, tried many times but to no avail ?
this program was working fine in PowerBasic
« Last Edit: March 07, 2018, 08:06:10 PM by o2admin »

JRS

  • Guest
Re: Getting error type mismatch when compiling
« Reply #1 on: March 07, 2018, 08:10:12 PM »
Hi Karen,

The forum supports code syntax highlighting. For OxygenBasic use code=o2 to enable syntax highlighting for the post. I will try to get a list of codes posted for languages the forum supports syntax highlighting for.


I may be wrong but don't you have to use a _ character at the end of each line that is a continuation of one statement?

« Last Edit: March 07, 2018, 08:34:02 PM by John »

Aurel

  • Guest
Re: Getting error type mismatch when compiling
« Reply #2 on: March 07, 2018, 10:32:03 PM »
Karen this one is from VB samples and work in o2...
for declaration I always use in one line..

Code: [Select]
' Declarations and such needed for the example:in Visual Basic
' (Copy them to the (declarations) section of a module.)
Declare Function GetVolumeInformation Lib "kernel32.dll" Alias "GetVolumeInformationA" (ByVal RPName As String, ByVal VNBuff As String, ByVal VNSize As Long, VSNum As Long, MaxL As Long, Flags As Long, ByVal SysBuffer As String, ByVal SysSize As Long) As Long

' Display the volume label, serial number, and file system name
' of the C: drive.  Note how the serial number value is manipulated to
' display it properly.
Dim volname As String   ' receives volume name of C:
Dim sn As Long          ' receives serial number of C:
Dim snstr As String     ' display form of serial number
Dim maxcomplen As Long  ' receives maximum component length
Dim sysflags As Long    ' receives file system flags
Dim sysname As String   ' receives the file system name
Dim retval As Long      ' return value
'right$ macro
Macro RightS(s,i)
mid(s,(-i))
end macro

' Initialize string buffers.
volname = Space(256)
sysname = Space(256)
' Get information about the C: drive's volume.
retval = GetVolumeInformation("C:\", volname, Len(volname), sn, maxcomplen, sysflags, sysname, Len(sysname))
' Remove the trailing nulls from the two strings.
volname = Left(volname, InStr(volname, chr(0)) - 1)
sysname = Left(sysname, InStr(sysname, chr(0)) - 1)
' Format the serial number properly.
snstr = LTrim(Hex(sn))
snstr = String(8 - Len(snstr), "0") + snstr
snstr = Left(snstr, 4) & "-" + RightS(snstr, 4)
' Display the volume name, serial number, and file system name.
Print "Volume Name: "+ volname
Print "Serial Number: "+ snstr
Print "File System: "+sysname

Charles Pegge

  • Guest
Re: Getting error type mismatch when compiling
« Reply #3 on: March 07, 2018, 11:51:34 PM »
Hi Karen,

I had to make it readable first. I lose my way in long lines but here goes:

RTL64 included twice
line break after Alias
bycopy is redundant
definitions required for hiwrd & lowrd
the call requires buffers to be set to null when not used
if you use the buffers then give the len instead of sizeof

Code: [Select]
    $ filename "GetHDDSerial_64.exe"
    use rtl64
    use minwin
     
'beware line break after alias
% hiwrd hiword
% lowrd loword
% bycopy

    DECLARE FUNCTION GetVolumeInformation Lib "kernel32.dll" Alias "GetVolumeInformationA" (
      ByVal lpRootPathName As String,
      ByVal lpVolumeNameBuffer As String,
      ByVal nVolumeNameSize As Long,
      ByRef lpVolumeSerialNumber As Long,
      ByRef lpMaximumComponentLength As Long,
      ByRef lpFileSystemFlags As Long,
      ByVal lpFileSystemNameBuffer As String,
      ByVal nFileSystemNameSize As Long) As Long
     
    '==========================================
    ' Obtain the Hard Drive Serial number
    FUNCTION DriveSerialNumber(Drive AS STRING) AS STRING
    LOCAL HWord AS DWORD
    LOCAL LWord AS DWORD
    LOCAL Volname AS  STRING
    LOCAL VolBuffer AS  STRING 
    LOCAL lpVolumeSerialNumber AS LONG
    LOCAL lpMaximumComponentLength AS LONG
    LOCAL lpFileSystemFlags AS LONG
    LOCAL FileSysBuffer AS STRING
    IF GetVolumeInformation (
         Drive,
         null, 'VolBuffer,
         0,    'len(VolBuffer),
         lpVolumeSerialNumber,
         lpMaximumComponentLength,
         lpFileSystemFlags,
         null,'FilesysBuffer,
         0    'len(FilesysBuffer)
        ) <> 0 THEN
        HWord = HIWRD(lpVolumeSerialNumber)
        LWord = LOWRD(lpVolumeSerialNumber)
        FUNCTION = RIGHT$("0000000"+HEX$(HWord), 4)  + RIGHT$("0000000"+HEX$(LWord), 4)
    ELSE
        FUNCTION = "Cannot Read Drive.."
    END IF
     
    END FUNCTION

     
     
    '===================================
        DIM AS STRING  Dsn , dDrive
         dDrive = "c:\"
         Dsn = DriveSerialNumber(dDrive)
         print  Dsn

José Roca

  • Guest
Re: Getting error type mismatch when compiling
« Reply #4 on: March 08, 2018, 12:21:59 AM »
These VB-like translations of the API headers hurt my eyes.

JRS

  • Guest
Re: Getting error type mismatch when compiling
« Reply #5 on: March 08, 2018, 12:52:42 AM »
These VB-like translations of the API headers hurt my eyes.

I would love to see your includes running under O2.

Arnold

  • Guest
Re: Getting error type mismatch when compiling
« Reply #6 on: March 08, 2018, 02:21:32 AM »
Hi Charles,

I used this example to try out unprototyped WinApi functions. Would this way be ok or is it not preferred?. I used the AddressOf operator at the places where you defined ByRef. This would also correspond to the description in the Win32 Help file.

As always it is interesting to see the various ways to achieve results in Oxygenbasic.

Roland

Code: [Select]
   $ filename "GetHDDSerial.exe"

   'use rtl64
   'use rtl32

    use minwin

    extern lib "Kernel32.dll"
    ! GetVolumeInformation        "GetVolumeInformationA"     '8
    end extern
 
    '==========================================
    ' Obtain the Hard Drive Serial number
    FUNCTION DriveSerialNumber(string Drive) AS STRING
    dword HWord, LWord
    string Volname = space 512, VolBuffer = space 512 
    long lpVolumeSerialNumber, lpMaximumComponentLength, lpFileSystemFlags
    string FileSysBuffer = space 256
   
    if GetVolumeInformation (
         Drive,
         VolBuffer,
         len(VolBuffer),
         @lpVolumeSerialNumber,
         @lpMaximumComponentLength,
         @lpFileSystemFlags,
         FilesysBuffer,
         len(FilesysBuffer)
        ) <> 0 then
        HWord = HIWoRD(lpVolumeSerialNumber)
        LWord = LOWoRD(lpVolumeSerialNumber)

print "lpMaximumComponentLength = " lpMaximumComponentLength
print "lpFileSystemFlags = 0x" hex lpFileSystemFlags
print "VolBuffer = " ltrim(rtrim(VolBuffer))
print "FilesysBuffer = " ltrim(rtrim(FilesysBuffer))       

        FUNCTION = "0000000" HEX(HWord, 4) "0000000" HEX(LWord, 4)
    else
        FUNCTION = "Cannot Read Drive.."
    end if
     
    END FUNCTION

     
     
    '===================================
    string  Dsn , dDrive
    dDrive = "c:\"
    Dsn = DriveSerialNumber(dDrive)
    print  "Dsn = " Dsn 

Charles Pegge

  • Guest
Re: Getting error type mismatch when compiling
« Reply #7 on: March 08, 2018, 02:54:44 AM »
Hi Roland,

Yes, I was thinking the same way. Get all your details from MSDN, and set your params explicitly.

 A complex call like this needs some documentation, pasted in situ.
Code: [Select]
/*
BOOL WINAPI GetVolumeInformation(
  _In_opt_  LPCTSTR lpRootPathName,
  _Out_opt_ LPTSTR  lpVolumeNameBuffer,
  _In_      DWORD   nVolumeNameSize,
  _Out_opt_ LPDWORD lpVolumeSerialNumber,
  _Out_opt_ LPDWORD lpMaximumComponentLength,
  _Out_opt_ LPDWORD lpFileSystemFlags,
  _Out_opt_ LPTSTR  lpFileSystemNameBuffer,
  _In_      DWORD   nFileSystemNameSize
);
*/
« Last Edit: March 08, 2018, 03:02:12 AM by Charles Pegge »

jcfuller

  • Guest
Re: Getting error type mismatch when compiling
« Reply #8 on: March 08, 2018, 06:11:27 AM »
Charles,
This is probably a DUH but if OxygenBasic's default passing is byref why do you need the AddresOf operator with the call?

James

Aurel

  • Guest
Re: Getting error type mismatch when compiling
« Reply #9 on: March 08, 2018, 06:51:28 AM »
Quote
These VB-like translations of the API headers hurt my eyes.
Heh..probably hurt your eyes because  is not your translation..
but
from my experience every VB Api example from net work properly in Oxygen Basic.

José Roca

  • Guest
Re: Getting error type mismatch when compiling
« Reply #10 on: March 08, 2018, 07:25:45 AM »
It hurts my eyes because declaring asciiz strings as strings and dwords as longs can only be seen in API declares for Visual Basic, that did it because VB had no support for these data types. It is so hard to do the translation correctly instead of copying a VB declare found in the web?

Charles Pegge

  • Guest
Re: Getting error type mismatch when compiling
« Reply #11 on: March 08, 2018, 08:11:39 AM »
Hi James,

The byref default only applies to Basic-style prototypes, where you specify 'AS'. PB/VB use this convention but FB switched to byval default a few years ago.

You can switch this compiler modality on at any line in the code with #byval, and back again with #byref. (I know you know that).

My preference is to use the C format, or our more relaxed compact C format, with explicit '*'. It is so much easier on the eye, and easier to port too.

As for unprototyped calls, o2 makes assumptions that UDT variables are byref, strings are dereferenced to be char pointers of some sort, floating point is passed as single byval,and the rest are integer primitives byval of any width up to 32/64 bits, according to platform.
« Last Edit: March 08, 2018, 08:26:32 AM by Charles Pegge »

Karen Zibowski

  • Guest
Re: Getting error type mismatch when compiling
« Reply #12 on: March 08, 2018, 08:40:33 AM »
Many Thanks to all of you
It makes this forum works well

Regards
Karen

jcfuller

  • Guest
Re: Getting error type mismatch when compiling
« Reply #13 on: March 08, 2018, 09:18:29 AM »
Charles,
If it was prototyped like this we would not need the AddressOf operator??
! GetVolumeInformation Lib "kernel32.dll" Alias "GetVolumeInformationA"( char*,char*,long,long*,long*,long*,char*,long)

And could call it like:
    if GetVolumeInformation (
         Drive,
         VolBuffer,
         len(VolBuffer),
         lpVolumeSerialNumber,
         lpMaximumComponentLength,
         lpFileSystemFlags,
         FilesysBuffer,
         len(FilesysBuffer)
        ) <> 0 then

James

JRS

  • Guest
Re: Getting error type mismatch when compiling
« Reply #14 on: March 08, 2018, 09:49:24 AM »
Quote
If it was prototyped like this we would not need the AddressOf operator??

Like another slice of Bacon:(

I like the DLLC dynamic FFI method of defining APIs. Just define what you need on the fly.