Convert VB Code into COBOL Code

[Migrated content. Thread originally posted on 31 January 2011]

Hi all,

I'm using Visual Code (2008) edition and i need to find out how to convert the following VB code into COBOL code.

I have a DLL on my system called “Winscard.dll” but I can’t get my project to access it.

The code I’m trying to convert is :-
Public Declare Function SCardEstablishContext Lib "Winscard.dll" (ByVal dwScope As Integer, _
ByVal pvReserved1 As Integer, _
ByVal pvReserved2 As Integer, _
ByRef phContext As Integer) As Integer

And I’ve tried adding the DLL as a project ref but cant seem to access it.

Any ideas/help much appreciated as I'm a bit stuck at the moment.

Many thanks

Neil.

  • If this is a native project you should be able to link with library called Winscard.lib.

    The API SCardEstablishContext is WinAPI, so you would need to call SCardEstablishContext with call-convention 74, also because it is not all upper characters in the API, use the compiler directive CASE too.

    If it is managed application you can CALL it in the same way but instead of linking with Winscard.lib use ILPINVOKE"winscard.dll" (or add a reference to the winscard.dll) and ensure you target the right bit'ness too... ie: through the IDE target x86 or use ILTARGET"x86" or ILTARGET"x64".
  • Are you converting to managed code or unmanaged code COBOL?
    Net Express or Visual COBOL?

    If you are converting to an unmanaged code COBOL program you can do this as follows:


    $SET CASE
    01 dwScope     pic x(4) comp-5.
    01 pvReserved1 pic x(4) comp-5.
    01 pvReserved2 pic x(4) comp-5.
    01 phContext   pic x(4) comp-5.
    01 retValue    pic x(4) comp-5.
    01 procPtr     procedure-pointer.
    procedure division.

        set procPtr to entry "Winscard.dll"
        call "SCardEstablishContext"
            using by value dwScope
                           pvReserved1
                           pvReserved2
                  by reference phContext
            returning retValue
        end-call
                             
  • hi, to be honest i dont mind which way the code is done as long as it works.

    i am using visual studio 2008 with nx5.1 so if it can be done any .NET way that i'm assuming that would be a better way to handle the code.

    can you pls also advise how to convert to COBOL the "ALIAS" command, see lines of VB code below:-

    Public Declare Function SCardListReaders Lib "Winscard.dll" Alias "SCardListReadersA"
    (ByVal hContext As Integer, _
    ByVal mzGroup As String, _
    ByVal ReaderList As String, _
    ByRef pcchReaders As Integer) As Integer

    i have tried the following:-

    set procPtr to entry "Winscard.dll"
    call "SCardListReadersA"
    using by value hContext
    mzGroup
    ReaderList
    by reference pcchReaders
    returning retValue
    end-call

    but it doesnt work and the IDE shows a warning on the retValue of

    Warning 1 Number of parameters in CALL (4) different from number in target method (0)

    many thanks for your help.
  • actually its almost working except returning the card reader name, so thought i would post the full vb code that need converting in case i'm missing something.

    Private Sub frmMain_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

    For ctr = 0 To 255
    sReaderList = sReaderList vbNullChar
    Next

    ReaderCount = 255

    ' 1. Establish context and obtain G_hContext handle
    G_retCode = ModWinsCard.SCardEstablishContext(ModWinsCard.SCARD_SCOPE_USER, 0, 0, G_hContext)

    If G_retCode <> ModWinsCard.SCARD_S_SUCCESS Then
    WriteLog(GetScardErrMsg(G_retCode))
    Exit Sub
    End If

    ' 2. List PC/SC card readers installed in the system
    G_retCode = ModWinsCard.SCardListReaders(G_hContext, "", sReaderList, ReaderCount)

    If G_retCode <> ModWinsCard.SCARD_S_SUCCESS Then
    WriteLog(GetScardErrMsg(G_retCode))
    Exit Sub
    End If

    Call LoadListToControl(cbReaderList, sReaderList)
    cbReaderList.SelectedIndex = 0

    ioRequest.dwProtocol = Protocol
    ioRequest.cbPciLength = Len(ioRequest)

    WriteLog("Program Ready")
    WriteLog("Select reader, insert mcu card and connect.")

    End Sub

    Public Declare Function SCardEstablishContext Lib "Winscard.dll" (ByVal dwScope As Integer, _
    ByVal pvReserved1 As Integer, _
    ByVal pvReserved2 As Integer, _
    ByRef phContext As Integer) As Integer

    Public Declare Function SCardListReaders Lib "Winscard.dll" Alias "SCardListReadersA" (ByVal hContext As Integer, _
    ByVal mzGroup As String, _
    ByVal ReaderList As String, _
    ByRef pcchReaders As Integer) As Integer

    Im getting values in pcchReaders of 54 which is the length of the string that should be in ReaderList but its null.

    Really appreciate your help in sorting this out.




  • The strings should be passed by reference in COBOL and should be NULL terminated.
    Try:


    call "SCardListReaderA"
       using by value hContext
             by reference mzGroup
                          ReaderList
                          pcchReaders
       returning retValue
    end-call
  • Sorry but that does work.

    I have got the following code to work except for returning the Card Readers name in ReaderList it just shows null. However if I use the VB code then it returns the Card Readers name which is a string that is 54 chars long. Which my Cobol program does return in the pcchReaders field i.e. if i hover over this field in the IDE debug it starts as 255 but once performed the function it has a value of 54 in it.

    Can some one pls advise what I am doing wrong as Im struggling to convert the VB code into COBOL.

    My current code as it stands is:-

    method-id. "ListReaders" public static.
    local-storage section.
    01 mzGroup string value "".
    01 ReaderList string value null.
    01 pcchReaders binary-long.
    01 phContext binary-long.
    01 retValue binary-long.
    01 procPtr procedure-pointer.
    procedure division returning lnk-key as string.
    * Public Declare Function SCardListReaders Lib "Winscard.dll" Alias "SCardListReadersA"
    * (ByVal hContext As Integer, _
    * ByVal mzGroup As String, _
    * ByVal ReaderList As String, _
    * ByRef pcchReaders As Integer) As Integer


    set phContext to -855572480
    set pcchReaders to 255

    set procPtr to entry "Winscard.dll"
    call "SCardListReadersA"
    using by value phContext
    by value mzGroup
    by value ReaderList
    by reference pcchReaders
    returning retValue
    end-call

    set lnk-key to retValue
    set lnk-key to retValue.
    goback.
    end method "ListReaders".
  • Just found out if I take the following lines out of the VB code it also returns blank.

    For ctr = 0 To 255
    sReaderList = sReaderList vbNullChar
    Next

    ReaderCount = 255

    Could some one pls advise what the COBOL code is for this?

    Many thanks
  • In your VB code:
    For ctr = 0 To 255
    sReaderList = sReaderList vbNullChar
    Next

    ReaderCount = 255

    What is sReaderList declared as? What is the purpose of that loop?
  • from VB code:-

    Dim sReaderList As String

    but i dont know why it does it but i do know if i take out

    For ctr = 0 To 255
    sReaderList = sReaderList vbNullChar
    Next
    or

    ReaderCount = 255

    then i dont get any values if sReaderList how ever if i run the code as above i get :-

    "SCM Microsystems Inc. SCR33x USB Smart Card Reader 0"

    but although the COBOL code will return a value in ReaderCount im still getting nothing in sReaderList
  • Verified Answer

    The following code works for me and returns a good result:


          $set ILPINVOKE"winscard.dll"
           id division.                                                   
           program-id.   testreaders.                                     
           special-names.                                                 
              call-convention 66 is winapi.                               
           working-storage section.                                       
           78 SCARD-SCOPE-USER        value 0.                               
           01 phContext    binary-long.                           
           01 mzGroup      pic x(256) value spaces.                       
           01 ReaderList   pic x(256) value all low-values.               
           01 pcchReaders  binary-long.                                   
           01 retValue     binary-long.                                   
           procedure division.                                           
                                                                   
              call winapi "SCardEstablishContext"                         
                 using by value SCARD-SCOPE-USER                                         
                       by value 0                                         
                       by value 0                                         
                       by reference phContext                             
                 returning RetValue                                       
              end-call                                                   
                                                                   
              move length of ReaderList to pcchReaders                                     
                                                                           
              call winapi "SCardListReadersA"                             
                 using by value phContext                                 
                       by value 0                                         
                       by reference ReaderList                           
                       by reference pcchReaders                           
                 returning retValue                                       
              end-call                                                   
                                                                   
              stop run.