I am Including an Email I sent to Sergio.Hopefully to get some of you really bright folks interested in playing with using VB6 written DLLs with Blitz3D..It works...
the Vb6 Addin vbAdvance is at www.vbAdvance.com..and is free to try...
=Email:
Sergio:
The Code is so short I am sending in the Email.. Cut/Paste...
Note: Got Forms working ... Except can only use MODAL..if you figure
out how to use MODELESS please let me know...
Project:
1. Download and install vbAdvance..it is an ADDIN..
2. Create VBProject.. Activex DLL...Namethe prj "ExportTest" (Name is used in code)
3. Create Module MExports.. paste MEXPORTS code below
4. Create FORM name FORM1 add text box (text1)..Command (Command1)..Paste form1
Code below
5. VB Tools/Add In Manager.. Select VbAvance.. a Floating toolbar (VbAdvance)
will show up... select the first button (Advanced options) then select
the DLL tab and Check the Functions/Subs to EXPORT ...
Note you DO NOT have to select InitVBEngine and Cleanup..only the Subs/Functions
you will be calling from Blitz3D...
6. Save the Project as ExportExample
7. Vb6 Files/ Make EXPORTEXAMPLE.DLL ... make sure the DLL is created in
Blitz3ds USERLIBS dir...
8. Create the Blitz3d code below
9. Create the ExportExample.decls in the blitz3d USERLIBS dir..
10. Run the blitz program
in testing /Using .. I saw MEMORY ACCESS VIOLATION alot...
usually meant I did NOT select the Function/Sub in step 5 or my Blitz Decls
were wrong.. OR..
I did not INITIALIZE THE VB ENGINE.. the Code InitVbEngine / Cleanup
has to be used...Read the explanation in the vbAdvance documentation
Also I put MsgBox code in the vb6 to let me know where it is.. did not bother to cleanup
happy coding...
Marv
;=========================================================================
;Blitz3d Code for using VB6 DLL
Const class$="Blitz Runtime Class" ; <- Blitz3D
Global title$="VB DLL" ; starting title
AppTitle title$
;Goto tint ; test Function/sub
;==== Std Hello Pass String to VB Sub
smsg$= "Str for VB Sub"
SayHello (smsg)
Goto tend
;==== Tested Vb DLL String function = Send/Receive"
.tStr
inpStr$="Send to vb function"
rtnst$ = vbStringFunction$( inpstr$)
Print inpStr$
Print Len(rtnst$)
Print rtnst$
Goto tEnd
;==== Send/Receive Float =====
.tfloat
inno# = 10
otNo#=vbFloatFunction#(inno#)
Print otno#
Goto tEnd
; ==== send/Receive Integer using Form ====
.tInt
inInt% = 1562
otInt%=vbIntegerFunction%(inInt%)
Print otint%
Goto tEnd
.tEnd
WaitKey()
End
;========= UserLibs Decls File=ExportExample.decls
;.lib "ExportExample.dll"
;vbStringFunction$ (z1$):"vbStringFunction"
;vbFloatFunction#(inNo#):"vbFloatFunction"
;vbIntegerFunction%(inNo%):"vbIntegerFunction"
;SayHello(Instr$):"SayHello"
;======End blitz ========================================
;
;
;===========Vb6
Project: ExportTest Active X DLL functions/Subs called by Blitz3d
Form1 Code:
'=======
Option Explicit
Private Sub Command1_Click()
Unload Me
End Sub
'=============
Module MExports Code
Option Explicit
'Required for initializing the VB engine:
Public pUnk As IUnknown
Public Function vbFloatFunction(ByVal inNo As Single) As Single
Dim sMsg As String
InitVBEngine "ExportTest.class1"
sMsg = "Rcvd= " & Str(inNo)
MessageBox 0&, sMsg, "Sub 04", 0&
vbFloatFunction = inNo * 10
CleanUp
End Function
Public Function vbIntegerFunction(ByVal inInt As Integer) As Integer
Dim sMsg As String
InitVBEngine "ExportTest.class1"
sMsg = "Rcvd= " & Str(inInt)
MessageBox 0&, sMsg, "Sub 04", 0&
vbIntegerFunction = inInt * 10
vbShowRcvd sMsg
CleanUp
End Function
Public Function vbStringFunction(ByVal lpMsg As Long) As String
' lpMsg is Ptr to C Style Str
Dim sMsg As String
Static stMsg As String
'Because the DLL is now registered, we can instantiate an object from this
'DLL, which will result in the VB runtime engine intializing:
InitVBEngine "ExportTest.class1"
'conv incoming str From UniCode (C style String using _StdCall)
sMsg = StrConv(SysAllocStringByteLen(lpMsg, lstrlen(lpMsg)), vbUnicode)
MessageBox 0&, sMsg, "Sub 04", 0&
'Insure null terminated
stMsg = "X23456789" + vbNullString
'Convert to ANSI (C style)
vbStringFunction = StrConv(stMsg, vbFromUnicode)
MessageBox 0&, stMsg, "Sub 04", 0&
' shut down VbRuntime Engine
CleanUp
End Function
Public Sub SayHello(ByVal lpMessage As Long)
Dim sMsg As String
InitVBEngine "ExportTest.class1"
'Convert the passed pointer to an ansi string into a VB String:
sMsg = StrConv(SysAllocStringByteLen(lpMessage, lstrlen(lpMessage)), vbUnicode)
'Pop a message box displaying the passed String:
MessageBox 0&, sMsg, "ExportExample", 0&
CleanUp
End Sub
Private Sub vbShowRcvd(sT As String)
On Error GoTo myError
Form1.Text1.Text = "Rcvd= " & sT
Form1.Show vbModal
Exit Sub
myError:
MsgBox "Error= " & Error$
End Sub
Public Function CleanUp()
'Release our object:
Set pUnk = Nothing
'And un-initialize OLE:
CoUninitialize
End Function
Public Sub InitVBEngine(sProgID As String)
Dim IID_IUnknown As VBGUID
Dim hr As Long
Dim CLSID As CLSID
Const FailBit As Long = &H80000000
Dim sMsg As String
sMsg = "In InitVB"
MessageBox 0&, sMsg, "Sub 04", 0&
'Initialize OLE:
hr = CoInitialize(0)
If hr And FailBit Then
MessageBox 0&, Error$, "Init Error", 0&
Exit Sub
End If
With IID_IUnknown
.Data4(0) = &HC0
.Data4(7) = &H46
End With
'Get the CLSID for the helper interface:
CLSID = CLSIDFromProgID(sProgID)
'Create the object:
hr = CoCreateInstance(CLSID, Nothing, CLSCTX_INPROC_SERVER, IID_IUnknown, pUnk)
If hr And FailBit Then
MsgBox Error$
CoUninitialize
Exit Sub
End If
'If we made it this far, then we can start using normal VB calls
'because we have an initialized VB object on this thread.
On Error GoTo myError
' Form1.Show (vbModal)
MsgBox "Leaving INITVB"
Exit Sub
myError:
MsgBox "Error= " & Error$
End Sub
'============================================
Code for CLASS1 class Module
No Code is needed for the Class1 (Class Module) but it must exist
'=========== EndCode===================
Answer to your other Questions:
> Would be possible, for example, to write a VB DLL wrapper for database use,
> ODBC, and so on.. extremely useful.
Answer: I have not tried it.. however vbAdvance is USING VB6.. it is not a seperate compiler...should work...
> Only a question though. You know already that a VB6 application needs lots
> of other DLLs and runtime library in order to work. Is that the same for a
> 'pure' "VB6 VB Advance" created DLL ?
Answer: the key to understanding what vbAdvance is doing .. VB6 from Msft has ALWAYS HAD the Capability
of Exporting Standard DLLs.. when Msft came up with ACTIVEX DLLs they simply did not give
us programmers the capability of Creating them.. the folks from vbAdvance fiquered that out and
are simply using VB6 compile options in the background to create Standard (Exported fucntions/Subs) DLLs
Therfore ALL VB6 capabilities are in the DLLs... vbAdvance is NOT GENERATING THE CODE..Msft VB6 is...
> In other words, if on the target pc there's no DLL and no library about VB6,
> would the DLL created using VB Advance work, as the Kernel32 or other basic
> DLL would ?
Answer: The VB RUNTIMES ARE NEEDED.....but it is free and could be included in your INSTALL..
I
the Vb6 Addin vbAdvance is at www.vbAdvance.com..and is free to try...
=Email:
Sergio:
The Code is so short I am sending in the Email.. Cut/Paste...
Note: Got Forms working ... Except can only use MODAL..if you figure
out how to use MODELESS please let me know...
Project:
1. Download and install vbAdvance..it is an ADDIN..
2. Create VBProject.. Activex DLL...Namethe prj "ExportTest" (Name is used in code)
3. Create Module MExports.. paste MEXPORTS code below
4. Create FORM name FORM1 add text box (text1)..Command (Command1)..Paste form1
Code below
5. VB Tools/Add In Manager.. Select VbAvance.. a Floating toolbar (VbAdvance)
will show up... select the first button (Advanced options) then select
the DLL tab and Check the Functions/Subs to EXPORT ...
Note you DO NOT have to select InitVBEngine and Cleanup..only the Subs/Functions
you will be calling from Blitz3D...
6. Save the Project as ExportExample
7. Vb6 Files/ Make EXPORTEXAMPLE.DLL ... make sure the DLL is created in
Blitz3ds USERLIBS dir...
8. Create the Blitz3d code below
9. Create the ExportExample.decls in the blitz3d USERLIBS dir..
10. Run the blitz program
in testing /Using .. I saw MEMORY ACCESS VIOLATION alot...
usually meant I did NOT select the Function/Sub in step 5 or my Blitz Decls
were wrong.. OR..
I did not INITIALIZE THE VB ENGINE.. the Code InitVbEngine / Cleanup
has to be used...Read the explanation in the vbAdvance documentation
Also I put MsgBox code in the vb6 to let me know where it is.. did not bother to cleanup
happy coding...
Marv
;=========================================================================
;Blitz3d Code for using VB6 DLL
Const class$="Blitz Runtime Class" ; <- Blitz3D
Global title$="VB DLL" ; starting title
AppTitle title$
;Goto tint ; test Function/sub
;==== Std Hello Pass String to VB Sub
smsg$= "Str for VB Sub"
SayHello (smsg)
Goto tend
;==== Tested Vb DLL String function = Send/Receive"
.tStr
inpStr$="Send to vb function"
rtnst$ = vbStringFunction$( inpstr$)
Print inpStr$
Print Len(rtnst$)
Print rtnst$
Goto tEnd
;==== Send/Receive Float =====
.tfloat
inno# = 10
otNo#=vbFloatFunction#(inno#)
Print otno#
Goto tEnd
; ==== send/Receive Integer using Form ====
.tInt
inInt% = 1562
otInt%=vbIntegerFunction%(inInt%)
Print otint%
Goto tEnd
.tEnd
WaitKey()
End
;========= UserLibs Decls File=ExportExample.decls
;.lib "ExportExample.dll"
;vbStringFunction$ (z1$):"vbStringFunction"
;vbFloatFunction#(inNo#):"vbFloatFunction"
;vbIntegerFunction%(inNo%):"vbIntegerFunction"
;SayHello(Instr$):"SayHello"
;======End blitz ========================================
;
;
;===========Vb6
Project: ExportTest Active X DLL functions/Subs called by Blitz3d
Form1 Code:
'=======
Option Explicit
Private Sub Command1_Click()
Unload Me
End Sub
'=============
Module MExports Code
Option Explicit
'Required for initializing the VB engine:
Public pUnk As IUnknown
Public Function vbFloatFunction(ByVal inNo As Single) As Single
Dim sMsg As String
InitVBEngine "ExportTest.class1"
sMsg = "Rcvd= " & Str(inNo)
MessageBox 0&, sMsg, "Sub 04", 0&
vbFloatFunction = inNo * 10
CleanUp
End Function
Public Function vbIntegerFunction(ByVal inInt As Integer) As Integer
Dim sMsg As String
InitVBEngine "ExportTest.class1"
sMsg = "Rcvd= " & Str(inInt)
MessageBox 0&, sMsg, "Sub 04", 0&
vbIntegerFunction = inInt * 10
vbShowRcvd sMsg
CleanUp
End Function
Public Function vbStringFunction(ByVal lpMsg As Long) As String
' lpMsg is Ptr to C Style Str
Dim sMsg As String
Static stMsg As String
'Because the DLL is now registered, we can instantiate an object from this
'DLL, which will result in the VB runtime engine intializing:
InitVBEngine "ExportTest.class1"
'conv incoming str From UniCode (C style String using _StdCall)
sMsg = StrConv(SysAllocStringByteLen(lpMsg, lstrlen(lpMsg)), vbUnicode)
MessageBox 0&, sMsg, "Sub 04", 0&
'Insure null terminated
stMsg = "X23456789" + vbNullString
'Convert to ANSI (C style)
vbStringFunction = StrConv(stMsg, vbFromUnicode)
MessageBox 0&, stMsg, "Sub 04", 0&
' shut down VbRuntime Engine
CleanUp
End Function
Public Sub SayHello(ByVal lpMessage As Long)
Dim sMsg As String
InitVBEngine "ExportTest.class1"
'Convert the passed pointer to an ansi string into a VB String:
sMsg = StrConv(SysAllocStringByteLen(lpMessage, lstrlen(lpMessage)), vbUnicode)
'Pop a message box displaying the passed String:
MessageBox 0&, sMsg, "ExportExample", 0&
CleanUp
End Sub
Private Sub vbShowRcvd(sT As String)
On Error GoTo myError
Form1.Text1.Text = "Rcvd= " & sT
Form1.Show vbModal
Exit Sub
myError:
MsgBox "Error= " & Error$
End Sub
Public Function CleanUp()
'Release our object:
Set pUnk = Nothing
'And un-initialize OLE:
CoUninitialize
End Function
Public Sub InitVBEngine(sProgID As String)
Dim IID_IUnknown As VBGUID
Dim hr As Long
Dim CLSID As CLSID
Const FailBit As Long = &H80000000
Dim sMsg As String
sMsg = "In InitVB"
MessageBox 0&, sMsg, "Sub 04", 0&
'Initialize OLE:
hr = CoInitialize(0)
If hr And FailBit Then
MessageBox 0&, Error$, "Init Error", 0&
Exit Sub
End If
With IID_IUnknown
.Data4(0) = &HC0
.Data4(7) = &H46
End With
'Get the CLSID for the helper interface:
CLSID = CLSIDFromProgID(sProgID)
'Create the object:
hr = CoCreateInstance(CLSID, Nothing, CLSCTX_INPROC_SERVER, IID_IUnknown, pUnk)
If hr And FailBit Then
MsgBox Error$
CoUninitialize
Exit Sub
End If
'If we made it this far, then we can start using normal VB calls
'because we have an initialized VB object on this thread.
On Error GoTo myError
' Form1.Show (vbModal)
MsgBox "Leaving INITVB"
Exit Sub
myError:
MsgBox "Error= " & Error$
End Sub
'============================================
Code for CLASS1 class Module
No Code is needed for the Class1 (Class Module) but it must exist
'=========== EndCode===================
Answer to your other Questions:
> Would be possible, for example, to write a VB DLL wrapper for database use,
> ODBC, and so on.. extremely useful.
Answer: I have not tried it.. however vbAdvance is USING VB6.. it is not a seperate compiler...should work...
> Only a question though. You know already that a VB6 application needs lots
> of other DLLs and runtime library in order to work. Is that the same for a
> 'pure' "VB6 VB Advance" created DLL ?
Answer: the key to understanding what vbAdvance is doing .. VB6 from Msft has ALWAYS HAD the Capability
of Exporting Standard DLLs.. when Msft came up with ACTIVEX DLLs they simply did not give
us programmers the capability of Creating them.. the folks from vbAdvance fiquered that out and
are simply using VB6 compile options in the background to create Standard (Exported fucntions/Subs) DLLs
Therfore ALL VB6 capabilities are in the DLLs... vbAdvance is NOT GENERATING THE CODE..Msft VB6 is...
> In other words, if on the target pc there's no DLL and no library about VB6,
> would the DLL created using VB Advance work, as the Kernel32 or other basic
> DLL would ?
Answer: The VB RUNTIMES ARE NEEDED.....but it is free and could be included in your INSTALL..
I