Results 1 to 22 of 22

Thread: DLL procedure call from VB6

  1. #1

    Thread Starter
    Hyperactive Member
    Join Date
    Sep 2012
    Posts
    433

    DLL procedure call from VB6

    This question may be so basic.
    To call DLL in C/C++, we should add(inform) .lib file of the DLL to the Linker.
    This .lib contains the information needed at run time.

    However VB6 calls DLL function which is exported without .lib.
    The function declaration has just function name, parameter, and DLL name in VB6's DLL procedure call.
    What is the difference between VB6 and C/C++ in DLL call?

  2. #2
    Smooth Moperator techgnome's Avatar
    Join Date
    May 2002
    Posts
    34,324

    Re: DLL procedure call from VB6

    The lib tells the linker where to find the function and how to call it... in VB6, that's done through the Declare format... same thing, same result, just a different means to get there.

    -tg
    * I don't respond to private (PM) requests for help. It's not conducive to the general learning of others.*
    * I also don't respond to friend requests. Save a few bits and don't bother. I'll just end up rejecting anyways.*
    * How to get EFFECTIVE help: The Hitchhiker's Guide to Getting Help at VBF - Removing eels from your hovercraft *
    * How to Use Parameters * Create Disconnected ADO Recordset Clones * Set your VB6 ActiveX Compatibility * Get rid of those pesky VB Line Numbers * I swear I saved my data, where'd it run off to??? *

  3. #3
    VB-aholic & Lovin' It LaVolpe's Avatar
    Join Date
    Oct 2007
    Location
    Beside Waldo
    Posts
    19,541

    Re: DLL procedure call from VB6

    Be sure to know what calling convention the DLL uses. VB6 does not play nicely with non stdCall conventions. For those more knowledgeable, does linking the DLL tell VB how to properly handle the clean up after the DLL call?

    Edited: Or will VB only allow linking to stdCall functions?
    Last edited by LaVolpe; Sep 3rd, 2015 at 02:36 PM.
    Insomnia is just a byproduct of, "It can't be done"

    Classics Enthusiast? Here's my 1969 Mustang Mach I Fastback. Her sister '67 Coupe has been adopted

    Newbie? Novice? Bored? Spend a few minutes browsing the FAQ section of the forum.
    Read the HitchHiker's Guide to Getting Help on the Forums.
    Here is the list of TAGs you can use to format your posts
    Here are VB6 Help Files online


    {Alpha Image Control} {Memory Leak FAQ} {Unicode Open/Save Dialog} {Resource Image Viewer/Extractor}
    {VB and DPI Tutorial} {Manifest Creator} {UserControl Button Template} {stdPicture Render Usage}

  4. #4
    PowerPoster
    Join Date
    Feb 2015
    Posts
    2,579

    Re: DLL procedure call from VB6

    VB6 allows work with CDECL calling convention too if this function was declared in tlb. But only at the compiled form.
    lib files can contain the executable code and any binary data. When you use the .lib-file it is called - "static linking". It may combine either executable code (or any data) or import section.
    You can use *lib-files in VB too.
    When you call function by Declare-statement then it performs the dynamic call (LoadLibrary, GetProcAddress only once for each function), therefore you can process error (for example if dll not exists), and using the alternative solution if needed. This method uses runtime for calling function by DllFunctionCall, this function fills the special structure in the PE-image in order for next time not perform the initialization. When you using tlb, lib (with import section) you can't process error because initialization of dll's going on at running time.

  5. #5
    Default Member Bonnie West's Avatar
    Join Date
    Jun 2012
    Location
    InIDE
    Posts
    4,060

    Re: DLL procedure call from VB6

    Quote Originally Posted by techgnome View Post
    ... same thing, ...
    Actually, they are not quite the same thing, as explained below.

    Quote Originally Posted by LaVolpe View Post
    Edited: Or will VB only allow linking to stdCall functions?
    That does seem to be the case, as implied here:

    Quote Originally Posted by MSDN
    Note If you use Visual C++ (or a similar tool) to create DLLs that will be called by Visual Basic, use the __stdcall calling convention. Do not use the default calling convention (_cdecl).
    EDIT Disregard that; didn't see The trick's post before I posted mine.

    Quote Originally Posted by jdy0803 View Post
    What is the difference between VB6 and C/C++ in DLL call?
    VB6 typically uses Run-Time Dynamic Linking while C/C++ often uses Load-Time Dynamic Linking. The KB article What is a DLL? concisely explained their differences:

    Quote Originally Posted by Microsoft
    Types of DLLs

    When you load a DLL in an application, two methods of linking let you call the exported DLL functions. The two methods of linking are load-time dynamic linking and run-time dynamic linking.

    Load-time dynamic linking

    In load-time dynamic linking, an application makes explicit calls to exported DLL functions like local functions. To use load-time dynamic linking, provide a header (.h) file and an import library (.lib) file when you compile and link the application. When you do this, the linker will provide the system with the information that is required to load the DLL and resolve the exported DLL function locations at load time.

    Run-time dynamic linking

    In run-time dynamic linking, an application calls either the LoadLibrary function or the LoadLibraryEx function to load the DLL at run time. After the DLL is successfully loaded, you use the GetProcAddress function to obtain the address of the exported DLL function that you want to call. When you use run-time dynamic linking, you do not need an import library file.
    Both VB6 and C/C++, however, supports both methods of linking. In VB6, run-time dynamic linking is normally achieved through the Declare statement. Load-time dynamic linking, on the other hand, can be accomplished by declaring a particular DLL's exported function(s) in a Type Library.
    Last edited by Bonnie West; Sep 3rd, 2015 at 04:06 PM.
    On Local Error Resume Next: If Not Empty Is Nothing Then Do While Null: ReDim i(True To False) As Currency: Loop: Else Debug.Assert CCur(CLng(CInt(CBool(False Imp True Xor False Eqv True)))): Stop: On Local Error GoTo 0
    Declare Sub CrashVB Lib "msvbvm60" (Optional DontPassMe As Any)

  6. #6
    Frenzied Member
    Join Date
    Jan 2010
    Posts
    1,103

    Re: DLL procedure call from VB6

    Mark this thread.
    Does VBForums has a function to add and save favorite thread?

  7. #7
    PowerPoster
    Join Date
    Jun 2015
    Posts
    2,224

    Re: DLL procedure call from VB6

    Quote Originally Posted by Jonney View Post
    Mark this thread.
    Does VBForums has a function to add and save favorite thread?
    Right?

    For the life of me I can't get the unsupported CDecl declarations to work in a compiled wrapper DLL. It should be as simple as creating a basic ActiveX DLL, with the Declared CDecl Declare, and compiling. I'm willing to go the typelib route - before I try and build the DLL using __stdcall but that's a last resort. Setting up a complete build environment for some of these open source projects can be quite a pain.

  8. #8
    VB-aholic & Lovin' It LaVolpe's Avatar
    Join Date
    Oct 2007
    Location
    Beside Waldo
    Posts
    19,541

    Re: DLL procedure call from VB6

    @Dex. The DispCallFunc API can be used to call cdecl APIs. If a callback is required, I have a project in the codebank that will assist there too.
    Insomnia is just a byproduct of, "It can't be done"

    Classics Enthusiast? Here's my 1969 Mustang Mach I Fastback. Her sister '67 Coupe has been adopted

    Newbie? Novice? Bored? Spend a few minutes browsing the FAQ section of the forum.
    Read the HitchHiker's Guide to Getting Help on the Forums.
    Here is the list of TAGs you can use to format your posts
    Here are VB6 Help Files online


    {Alpha Image Control} {Memory Leak FAQ} {Unicode Open/Save Dialog} {Resource Image Viewer/Extractor}
    {VB and DPI Tutorial} {Manifest Creator} {UserControl Button Template} {stdPicture Render Usage}

  9. #9
    PowerPoster
    Join Date
    Jun 2013
    Posts
    6,974

    Re: DLL procedure call from VB6

    Quote Originally Posted by DEXWERX View Post
    Setting up a complete build environment for some of these open source projects can be quite a pain.
    Care to share, which open C-source project you're trying to wrap?

    Olaf

  10. #10
    PowerPoster
    Join Date
    Jun 2015
    Posts
    2,224

    Re: DLL procedure call from VB6

    Quote Originally Posted by Schmidt View Post
    Care to share, which open C-source project you're trying to wrap?

    Olaf
    SDL2 / Simple Direct Media Layer. It's a media/game dev API. I'd like to forgo the DispCallFunc overhead, so compiling using STDCALL is still a big option.

  11. #11

  12. #12
    VB-aholic & Lovin' It LaVolpe's Avatar
    Join Date
    Oct 2007
    Location
    Beside Waldo
    Posts
    19,541

    Re: DLL procedure call from VB6

    Quote Originally Posted by The trick View Post
    Example of calling CDecl functions (wsprintf, wcstoul). Note it works only in the exe.
    I'll have to play with that idea sometime soon. Though, you said it only works when compiled? What would you suggest to also be able to use the DLLs during IDE? Maybe something like this?
    Code:
    #If uncompiled
        DispCallFunc routines
    #Else
        TLB calls
    #End If
    Insomnia is just a byproduct of, "It can't be done"

    Classics Enthusiast? Here's my 1969 Mustang Mach I Fastback. Her sister '67 Coupe has been adopted

    Newbie? Novice? Bored? Spend a few minutes browsing the FAQ section of the forum.
    Read the HitchHiker's Guide to Getting Help on the Forums.
    Here is the list of TAGs you can use to format your posts
    Here are VB6 Help Files online


    {Alpha Image Control} {Memory Leak FAQ} {Unicode Open/Save Dialog} {Resource Image Viewer/Extractor}
    {VB and DPI Tutorial} {Manifest Creator} {UserControl Button Template} {stdPicture Render Usage}

  13. #13
    PowerPoster
    Join Date
    Feb 2015
    Posts
    2,579

    Re: DLL procedure call from VB6

    Quote Originally Posted by LaVolpe View Post
    I'll have to play with that idea sometime soon. Though, you said it only works when compiled? What would you suggest to also be able to use the DLLs during IDE? Maybe something like this?
    Code:
    #If uncompiled
        DispCallFunc routines
    #Else
        TLB calls
    #End If
    Yes, it'll work. Usually i use other debugger, it allows to debug lot of things, such as multithreading, drivers, interceptions, etc.
    You can do the addin that fix the IDE problem, and then user can uses the cdecl convention without "crutches".

  14. #14
    VB-aholic & Lovin' It LaVolpe's Avatar
    Join Date
    Oct 2007
    Location
    Beside Waldo
    Posts
    19,541

    Re: DLL procedure call from VB6

    Quote Originally Posted by The trick View Post
    Yes, it'll work. Usually i use other debugger, it allows to debug lot of things, such as multithreading, drivers, interceptions, etc.
    You can do the addin that fix the IDE problem, and then user can uses the cdecl convention without "crutches".
    Can you expand on your comments more. I admit that I do not completely follow. For example, what exactly are you suggesting if we wanted to your your wsprintf TLB both during IDE & when compiled to exe?
    Insomnia is just a byproduct of, "It can't be done"

    Classics Enthusiast? Here's my 1969 Mustang Mach I Fastback. Her sister '67 Coupe has been adopted

    Newbie? Novice? Bored? Spend a few minutes browsing the FAQ section of the forum.
    Read the HitchHiker's Guide to Getting Help on the Forums.
    Here is the list of TAGs you can use to format your posts
    Here are VB6 Help Files online


    {Alpha Image Control} {Memory Leak FAQ} {Unicode Open/Save Dialog} {Resource Image Viewer/Extractor}
    {VB and DPI Tutorial} {Manifest Creator} {UserControl Button Template} {stdPicture Render Usage}

  15. #15
    PowerPoster
    Join Date
    Jun 2015
    Posts
    2,224

    Re: DLL procedure call from VB6

    Quote Originally Posted by The trick View Post
    Yes, it'll work. Usually i use other debugger, it allows to debug lot of things, such as multithreading, drivers, interceptions, etc.
    You can do the addin that fix the IDE problem, and then user can uses the cdecl convention without "crutches".
    I'm always curious what debugers people use, and (resource watchers). Also what IDE add-in would allow this?

  16. #16
    PowerPoster
    Join Date
    Feb 2015
    Posts
    2,579

    Re: DLL procedure call from VB6

    Quote Originally Posted by LaVolpe View Post
    Can you expand on your comments more. I admit that I do not completely follow. For example, what exactly are you suggesting if we wanted to your your wsprintf TLB both during IDE & when compiled to exe?
    As i imagine it:
    When user adds an item in the references, addin checks whether it's a typelib. If so, addin parses it and looking for all members that have the cdecl calling convention. Then addin dynamically creates typelib just replaces cdecl calling convention to stdcall and changes library name to special library.
    This library contains some functions that accept different numbers of parameters (these functions may be generated dynamically too). Each function from the library forms the stack (__stdcall -> __cdecl), and calls original function. Actually vb6 calls __stdcall function, therefore crash isn't happening. During compilation just replace typelib to original. You can synchronize all steps by the events.
    Quote Originally Posted by DEXWERX View Post
    I'm always curious what debugers people use, and (resource watchers). Also what IDE add-in would allow this?
    In order to embed the debugger to IDE you need spend very much times and efforts, because it's very difficult (many things is undocumented). I use simple debbuger that debugs executable files. I use OllyDbg for user mode debugging and Syser for kernel mode debugging.
    This is example of using OllyDbg for debugging vb6 code:

  17. #17
    PowerPoster
    Join Date
    Jun 2013
    Posts
    6,974

    Re: DLL procedure call from VB6

    Quote Originally Posted by DEXWERX View Post
    SDL2 / Simple Direct Media Layer. It's a media/game dev API. I'd like to forgo the DispCallFunc overhead, so compiling using STDCALL is still a big option.
    The DispCallFunc-Overhead isn't all that "critical" for most calls -
    it's only when you plan to e.g. render 20,000 lines for e.g. a "WireFrame-Model"
    in a tight loop, that differences might become more obvious - but for those
    kind of calls there often exist alternatives in the API like e.g. a "Polygon-" or
    "RenderPath-" call or something (where the Coords sit in structures you pass along).

    So, yeah - I'd perhaps go without a typelib, since a decent "Class-Wrapping" would
    have to be done anyways (each Flat-API represented behind a Class-method).

    I've just played a bit (for reasons of convenience with the builtin cdecl-support-calls
    of the RichClient, which are also faster than calls over DispCallFunc - especially
    New_c.cdeclCallDirect would be nearly as fast as a "natively declared call").

    The following Class-Module (please name it cSDL2) wraps already a good part of the
    "video"-functionality of SDL2-lib, so that most simple video-related examples on the
    SDL-site should be supported (when converted to VB6-syntax)....

    Code:
    Option Explicit
    
    Public Enum SDL_EventType
      SDL_FIRSTEVENT = 0
      SDL_QUIT_ = &H100
      SDL_APP_TERMINATING
      SDL_APP_LOWMEMORY
      SDL_APP_WILLENTERBACKGROUND
      SDL_APP_DIDENTERBACKGROUND
      SDL_APP_WILLENTERFOREGROUND
      SDL_APP_DIDENTERFOREGROUND
      SDL_WindowEvent = &H200
      SDL_SysWMEvent
      SDL_KEYDOWN = &H300
      SDL_KEYUP
      SDL_TEXTEDITING
      SDL_TEXTINPUT
      SDL_MOUSEMOTION = &H400
      SDL_MOUSEBUTTONDOWN
      SDL_MOUSEBUTTONUP
      SDL_MOUSEWHEEL
      SDL_JOYAXISMOTION = &H600
      SDL_JOYBALLMOTION
      SDL_JOYHATMOTION
      SDL_JOYBUTTONDOWN
      SDL_JOYBUTTONUP
      SDL_JOYDEVICEADDED
      SDL_JOYDEVICEREMOVED
      SDL_CONTROLLERAXISMOTION = &H650
      SDL_CONTROLLERBUTTONDOWN
      SDL_CONTROLLERBUTTONUP
      SDL_CONTROLLERDEVICEADDED
      SDL_CONTROLLERDEVICEREMOVED
      SDL_CONTROLLERDEVICEREMAPPED
      SDL_FINGERDOWN = &H700
      SDL_FINGERUP
      SDL_FINGERMOTION
      SDL_DOLLARGESTURE = &H800
      SDL_DOLLARRECORD
      SDL_MULTIGESTURE
      SDL_CLIPBOARDUPDATE = &H900
      SDL_DROPFILE = &H1000
      SDL_UserEvent = &H8000&
      SDL_LASTEVENT = &HFFFF&
    End Enum
    
    Public Enum SDL_LOG_CATEGORY
      SDL_LOG_CATEGORY_APPLICATION
      SDL_LOG_CATEGORY_ERROR
      SDL_LOG_CATEGORY_ASSERT
      SDL_LOG_CATEGORY_SYSTEM
      SDL_LOG_CATEGORY_AUDIO
      SDL_LOG_CATEGORY_VIDEO
      SDL_LOG_CATEGORY_RENDER
      SDL_LOG_CATEGORY_INPUT
      SDL_LOG_CATEGORY_TEST
    End Enum
    
    Public Enum SDL_LogPriority
      SDL_LOG_PRIORITY_VERBOSE = 1
      SDL_LOG_PRIORITY_DEBUG
      SDL_LOG_PRIORITY_INFO
      SDL_LOG_PRIORITY_WARN
      SDL_LOG_PRIORITY_ERROR
      SDL_LOG_PRIORITY_CRITICAL
    End Enum
    
    Public Enum SDL_INIT_FLAGS
      SDL_INIT_TIMER = &H1
      SDL_INIT_AUDIO = &H10
      SDL_INIT_VIDEO = &H20
      SDL_INIT_JOYSTICK = &H200
      SDL_INIT_HAPTIC = &H1000
      SDL_INIT_GAMECONTROLLER = &H2000
      SDL_INIT_EVENTS = &H4000
      SDL_INIT_NOPARACHUTE = &H100000
    End Enum
    
    Public Enum SDL_WindowFlags
      SDL_WINDOW_FULLSCREEN = &H1
      SDL_WINDOW_OPENGL = &H2
      SDL_WINDOW_SHOWN = &H4
      SDL_WINDOW_HIDDEN = &H8
      SDL_WINDOW_BORDERLESS = &H10
      SDL_WINDOW_RESIZABLE = &H20
      SDL_WINDOW_MINIMIZED = &H40
      SDL_WINDOW_MAXIMIZED = &H80
      SDL_WINDOW_INPUT_GRABBED = &H100
      SDL_WINDOW_INPUT_FOCUS = &H200
      SDL_WINDOW_MOUSE_FOCUS = &H400
      SDL_WINDOW_FULLSCREEN_DESKTOP = (SDL_WINDOW_FULLSCREEN Or &H1000)
      SDL_WINDOW_FOREIGN = &H800
      SDL_WINDOW_ALLOW_HIGHDPI = &H2000
    End Enum
     
    Public Enum SDL_RendererFlags
      SDL_RENDERER_SOFTWARE = &H1
      SDL_RENDERER_ACCELERATED = &H2
      SDL_RENDERER_PRESENTVSYNC = &H4
      SDL_RENDERER_TARGETTEXTURE = &H8
    End Enum
    
    Public Enum SDL_WINDOWPOS
      SDL_WINDOWPOS_UNDEFINED = &H1FFF0000
      SDL_WINDOWPOS_CENTERED = &H2FFF0000
    End Enum
    '****** end of Public EnumDefs (which will show up on the Class-Interface) *****
    
    'the rest is Private-stuff for Class-internal usage...
    
    'these two are used to convert Zero-terminated 8Bit-CharSequences into VBStrings
    Private Declare Function lstrlenA& Lib "kernel32" (ByVal lpszSrc&)
    Private Declare Function lstrcpyA& Lib "kernel32" (ByVal lpszDest$, ByVal lpszSrc&)
    
    'the SDL-Event-struct is a Union - but most "Sub-Structs" have at least the first 3 Members in common
    Private Type SDL_EVENT
      eType As SDL_EventType
      eTimeStamp As Long
      eID As Long
      eBytes(0 To 63) As Byte
    End Type
    Private mEvt As SDL_EVENT 'this Class-Variable is the one used for Polling
    
    'the below ENum is used as a "speaking Index" in conjunction with the Function-Table (vTbl) directly below
    Private Enum SDL_Methods
      SDL_LogSetPriority
      SDL_Init
      SDL_GetError
      SDL_CreateWindow
      SDL_GetWindowSurface
      SDL_CreateSoftwareRenderer
      SDL_CreateRenderer
      SDL_SetRenderDrawColor
      SDL_RenderClear
      SDL_RenderGetViewport
      SDL_RenderFillRect
      SDL_RenderPresent
      SDL_UpdateWindowSurface
      SDL_PollEvent
      SDL_FreeSurface
      SDL_DestroyRenderer
      SDL_DestroyWindow
      SDL_Quit
      '... put additional methods here
      
      SDL_MethodsCount
    End Enum
    Private vTbl(0 To SDL_MethodsCount - 1) As Long 'and here's our Private vTbl-Array for the Func-Pointers
    
    Private Sub Class_Initialize()
    Dim DllPath$: DllPath = App.Path & "\SDL2.dll"
        vTbl(SDL_LogSetPriority) = New_c.GetFuncPtr(DllPath, "SDL_LogSetPriority", True)
        vTbl(SDL_Init) = New_c.GetFuncPtr(DllPath, "SDL_Init", True)
        vTbl(SDL_GetError) = New_c.GetFuncPtr(DllPath, "SDL_GetError", True)
        vTbl(SDL_CreateWindow) = New_c.GetFuncPtr(DllPath, "SDL_CreateWindow", True)
        vTbl(SDL_GetWindowSurface) = New_c.GetFuncPtr(DllPath, "SDL_GetWindowSurface", True)
        vTbl(SDL_CreateSoftwareRenderer) = New_c.GetFuncPtr(DllPath, "SDL_CreateSoftwareRenderer", True)
        vTbl(SDL_CreateRenderer) = New_c.GetFuncPtr(DllPath, "SDL_CreateRenderer", True)
        vTbl(SDL_SetRenderDrawColor) = New_c.GetFuncPtr(DllPath, "SDL_SetRenderDrawColor", True)
        vTbl(SDL_RenderClear) = New_c.GetFuncPtr(DllPath, "SDL_RenderClear", True)
        vTbl(SDL_RenderGetViewport) = New_c.GetFuncPtr(DllPath, "SDL_RenderGetViewport", True)
        vTbl(SDL_RenderFillRect) = New_c.GetFuncPtr(DllPath, "SDL_RenderFillRect", True)
        vTbl(SDL_RenderPresent) = New_c.GetFuncPtr(DllPath, "SDL_RenderPresent", True)
        vTbl(SDL_UpdateWindowSurface) = New_c.GetFuncPtr(DllPath, "SDL_UpdateWindowSurface", True)
        vTbl(SDL_PollEvent) = New_c.GetFuncPtr(DllPath, "SDL_PollEvent", True)
        vTbl(SDL_FreeSurface) = New_c.GetFuncPtr(DllPath, "SDL_FreeSurface", True)
        vTbl(SDL_DestroyRenderer) = New_c.GetFuncPtr(DllPath, "SDL_DestroyRenderer", True)
        vTbl(SDL_DestroyWindow) = New_c.GetFuncPtr(DllPath, "SDL_DestroyWindow", True)
        vTbl(SDL_Quit) = New_c.GetFuncPtr(DllPath, "SDL_Quit", True)
        
        LogSetPriority SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO
    End Sub
    
    Public Function LogSetPriority(ByVal Cat As SDL_LOG_CATEGORY, ByVal Prio As SDL_LogPriority) As Long
      LogSetPriority = New_c.cdeclCall(retLong, vTbl(SDL_LogSetPriority), Cat, Prio)
    End Function
    
    Public Function Init(ByVal Flags As SDL_INIT_FLAGS) As Long
      Init = New_c.cdeclCall(retLong, vTbl(SDL_Init), Flags)
    End Function
    
    Public Function GetError() As String
    Dim pErrStr As Long, SLen As Long
        pErrStr = New_c.cdeclCall(retLong, vTbl(SDL_GetError))
        If pErrStr = 0 Then Exit Function Else SLen = lstrlenA(pErrStr)
        If SLen Then GetError = Space$(SLen): lstrcpyA GetError, pErrStr
    End Function
    
    Public Function CreateWindow(Caption As String, ByVal x&, ByVal y&, ByVal dx&, ByVal dy&, Optional ByVal Flags As SDL_WindowFlags = SDL_WINDOW_RESIZABLE) As Long
      CreateWindow = New_c.cdeclCall(retLong, vTbl(SDL_CreateWindow), StrPtr(StrConv(Caption, vbFromUnicode)), x, y, dx, dy, Flags)
    End Function
    
    Public Function GetWindowSurface(Window As Long) As Long
      GetWindowSurface = New_c.cdeclCall(retLong, vTbl(SDL_GetWindowSurface), Window)
    End Function
    
    Public Function CreateSoftwareRenderer(Surface As Long) As Long
      CreateSoftwareRenderer = New_c.cdeclCall(retLong, vTbl(SDL_CreateSoftwareRenderer), Surface)
    End Function
    
    Public Function CreateRenderer(Window As Long, Optional ByVal Flags As SDL_RendererFlags = SDL_RENDERER_SOFTWARE) As Long
      CreateRenderer = New_c.cdeclCall(retLong, vTbl(SDL_CreateRenderer), Window, -1, Flags)
    End Function
    
    Public Function SetRenderDrawColor(Renderer As Long, ByVal R As Byte, ByVal G As Byte, ByVal B As Byte, Optional ByVal A As Byte = 255) As Long
      SetRenderDrawColor = New_c.cdeclCall(retLong, vTbl(SDL_SetRenderDrawColor), Renderer, R, G, B, A)
    End Function
    
    Public Function RenderClear(Renderer As Long) As Long
      RenderClear = New_c.cdeclCall(retLong, vTbl(SDL_RenderClear), Renderer)
    End Function
    
    Public Sub RenderGetViewport(Renderer As Long, x As Long, y As Long, dx As Long, dy As Long)
    Static Rct(0 To 3) As Long
        New_c.cdeclCall retVoid, vTbl(SDL_RenderGetViewport), Renderer, VarPtr(Rct(0))
        x = Rct(0): y = Rct(1): dx = Rct(2): dy = Rct(3)
    End Sub
    
    Public Function RenderFillRect(Renderer As Long, ByVal x As Long, ByVal y As Long, ByVal dx As Long, ByVal dy As Long) As Long
    Static Rect(0 To 3) As Long
        Rect(0) = x: Rect(1) = y: Rect(2) = dx: Rect(3) = dy
        RenderFillRect = New_c.cdeclCall(retLong, vTbl(SDL_RenderFillRect), Renderer, VarPtr(Rect(0)))
    End Function
    
    Public Function UpdateWindowSurface(Window As Long) As Long
      UpdateWindowSurface = New_c.cdeclCall(retLong, vTbl(SDL_UpdateWindowSurface), Window)
    End Function
    
    Public Sub RenderPresent(Renderer As Long)
      New_c.cdeclCall retVoid, vTbl(SDL_RenderPresent), Renderer
    End Sub
    
    Public Function PollEvent(eType As SDL_EventType) As Long
      PollEvent = New_c.cdeclCall(retLong, vTbl(SDL_PollEvent), VarPtr(mEvt))
      eType = mEvt.eType
    End Function
    Public Function Event_KeySym() As KeyCodeConstants
      Event_KeySym = mEvt.eBytes(8) + 256& * mEvt.eBytes(9)
    End Function
    
    Public Sub FreeSurface(Surface As Long)
      New_c.cdeclCall retVoid, vTbl(SDL_FreeSurface), Surface
    End Sub
    Public Sub DestroyRenderer(Renderer As Long)
      New_c.cdeclCall retVoid, vTbl(SDL_DestroyRenderer), Renderer
    End Sub
    Public Sub DestroyWindow(Window As Long)
      New_c.cdeclCall retVoid, vTbl(SDL_DestroyWindow), Window
    End Sub
    
    Private Sub Class_Terminate()
      New_c.cdeclCall retVoid, vTbl(SDL_Quit)
    End Sub
    Here is "Sub Main()" code which implements the ChessBoard-example from the
    SDL-WebSite, translated to VB6-Wrapper-Code...
    The VB-Project needs a reference to RC5, and you should place the SDL2.dll
    directly in the App.Path (beside the *.vbp) ... using the latest (win-x86) version
    2.0.3 from the SDL-download page: https://www.libsdl.org/download-2.0.php

    Code:
    Option Explicit
    
    Public SDL2 As New cSDL2
    
    Sub Main()
    Dim Window As Long, Renderer As Long, eType As SDL_EventType
    
      If SDL2.Init(SDL_INIT_VIDEO) Then Err.Raise vbObjectError, , SDL2.GetError
     
      'Create a Host-Window and a Renderer
      Window = SDL2.CreateWindow("Chess-Board", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 640, 560)
      If Window = 0 Then Err.Raise vbObjectError, , SDL2.GetError
     
      Renderer = SDL2.CreateRenderer(Window, SDL_RENDERER_ACCELERATED Or SDL_RENDERER_PRESENTVSYNC)
      If Renderer = 0 Then Err.Raise vbObjectError, , SDL2.GetError
      
      Do Until eType = SDL_QUIT_ Or (eType = SDL_KEYDOWN And SDL2.Event_KeySym = vbKeyEscape)
        DrawChessBoard Renderer
        SDL2.RenderPresent Renderer 'update the View (flipping the Backbuf, whilst waiting for VSync)
     
        SDL2.PollEvent eType 'poll the Event-Status (before usage in the "Until"-condition at Loop-Entry)
      Loop
     
      SDL2.DestroyRenderer Renderer
      SDL2.DestroyWindow Window
    End Sub
    
    Sub DrawChessBoard(Renderer As Long)
    Dim Row&, Col&, x&, y&, dx&, dy&
        SDL2.SetRenderDrawColor Renderer, 255, 255, 255
        SDL2.RenderClear Renderer 'fill the entire render-area with the above color (white in this case)
     
        SDL2.RenderGetViewport Renderer, x, y, dx, dy 'get the Size of the viewport
        
        dx = dx \ 8: dy = dy \ 8 'adjust the retrieved client-area-dimensions to 1/8th
        
        For Row = 0 To 7: For Col = Row Mod 2 To 7 Step 2 'now render any second chessboard-rectangle...
          SDL2.SetRenderDrawColor Renderer, 0, 0, 0 '...with black color...
          SDL2.RenderFillRect Renderer, Col * dx, Row * dy, dx, dy '... and fill it
        Next Col, Row
    End Sub
    Then producing this:


    Something to play around with... maybe it's a good start for your own Binding
    (I think the VB6-community could use more such wrappers around OpenSource-libs -
    . another good candidate would be e.g. libGit, which also exists in a Windows-version).

    Good luck.

    Olaf

  18. #18
    PowerPoster
    Join Date
    Jun 2012
    Posts
    2,233

    Re: DLL procedure call from VB6

    Quote Originally Posted by The trick View Post
    Example of calling CDecl functions (wsprintf, wcstoul). Note it works only in the exe.
    Your solution uses a tlb. But in order to have a exe solution only wouldn't it be easier to use the VB6's undocumented CDecl decorator ?

    Code:
    Private Declare Function TestFuncCDecl CDecl Lib "CDeclDll" (ByVal lpDummy As Long) As Long
    Downside is that p-code compilation does not work. Only in native code compilation.

  19. #19
    PowerPoster
    Join Date
    Feb 2015
    Posts
    2,579

    Re: DLL procedure call from VB6

    Quote Originally Posted by Krool View Post
    Your solution uses a tlb. But in order to have a exe solution only wouldn't it be easier to use the VB6's undocumented CDecl decorator ?

    Code:
    Private Declare Function TestFuncCDecl CDecl Lib "CDeclDll" (ByVal lpDummy As Long) As Long
    Downside is that p-code compilation does not work. Only in native code compilation.
    No. It doesn't work at all because it'll compile to unconditional error generation code:

    It even doesn't check if library exist.

  20. #20
    PowerPoster
    Join Date
    Jun 2012
    Posts
    2,233

    Re: DLL procedure call from VB6

    Quote Originally Posted by The trick View Post
    No. It doesn't work at all because it'll compile to unconditional error generation code:

    It even doesn't check if library exist.
    Hmm. What is then the sense of that CDecl keyword?

  21. #21
    PowerPoster
    Join Date
    Jun 2015
    Posts
    2,224

    Re: DLL procedure call from VB6

    Quote Originally Posted by Krool View Post
    Hmm. What is then the sense of that CDecl keyword?
    Right? I guess it was a "todo" that MS never got around to.

    @the trick - thanks for confirming this. seeing what VB compiles to code has been invaluable.

  22. #22

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width