Visual Basic DLL- It Does Work

Blitz3D Forums/Blitz3D Beginners Area/Visual Basic DLL- It Does Work

augGa(Posted 2003) [#1]
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


semar(Posted 2003) [#2]
@Kurtz,
Thanks a lot m8 !

:)

Sergio.


augGa(Posted 2003) [#3]
1. solved the MODAL problem use following to show MODELESS:
Private Declare Function ShowWindow& Lib "user32" (ByVal hwnd As Long, ByVal nCmdShow As Long)
Private Const SW_SHOWNORMAL& = 1
-and to display form as Modeless-
Load Form1
lRes = ShowWindow(Form1.hwnd, SW_SHOWNORMAL)

2. Wrote a quick blitz pgm to pass a "Name" and random no. to a vb6 dll function that stores in MS Access Data base..works fine..iterated 1000 times..ran fast...used ADO


Beaker(Posted 2003) [#4]
Great that it can be done, and I'm sure there are good reasons for doing it, but, what are they?


augGa(Posted 2003) [#5]
Masterbreaker...
well.. instead of using C,Purebasic etc pgm langs. to write DLLs for use in Blitz this opens up msft VISUAL BASIC for use..VB pretty much allows programmers to do ANYTHING within the Windows OS.. there are alot of VB programmers out there...some who do not do game pgming (like me) but might want to use BLITZ to EASILY Show 3D representations of real world situations..
I have followed your posts.. you , Dr Av and others are bright folks..your thoughts and comments are appreciated...
one example (from a Non Gamer) suppose you wanted to keep scores for a game.. lots of ways to do it.. free with windows is ODBC (Jet/ADO) Data Base.. ..Yes a dll in C++,Others could be written.. But it was Designed to be used by VB, easily and little code.. or (another example) suppose you want to(from within Blitz) EMAIL "something" to a given list..can do..or (another example) I want to add PopUp menus to my Blitz app-can't do easily in Blitz so I'll use a VB DLL to do it.. SQL,DirectX internals,Sockets, ENTIRE WINDOWS API is Easily accessible from VB. You want FAST CALCULATIONS..ASM can be imbeded within VB.. What can it do? What do you want to do..there is so much VB code out there I would guess someone found a way to do it...do you want your Blitz code to interface to Msft Access,Excel,Outlook..ANY MSFT (and other) products?..or do you have a Non Blitz app that you want to interface to Blitz...I don't know why you would (it's your imagination not mine)..but if you want to you can through a VB DLL....


Beaker(Posted 2003) [#6]
I suspected database stuff might come into it. Thanks for your explanation.


semar(Posted 2003) [#7]
Cheers Kurtz,
your progressing in this field are very interesting and really promising.

I'll try to be as productive as you in this field..

Best Regards,
Sergio.

P.S.
The only drawback about a VB6 DLL is that it needs the VB runtime DLLs to run, while a DLL written in C++ does not...


Andy_A(Posted 2003) [#8]
Kurtz,

Nicely done.

Using this method of accessing the VB runtime DLL, would it be possible to create a print dialog window generated in a Blitz program to print .bmp's in color? Or better still, to format the print output like one does in MS Access form generator with graphics, fonts, and page orientation?


augGa(Posted 2003) [#9]
@Andy_A
Yes...

I have not played with printing yet..will need to at some point.. at this time I am adding standard windows menus to my blitz app..(popups) and changing my app to use MDB instead of INI's ...


jcosch(Posted 2004) [#10]
I would like to use a dll created in VB6 with Blitz so Kurt's procedure above is very interesting. I have tried following the procedure step by step, but I am having a lot of trouble getting the dll to compile without error. The errors I get are from functions and data types not recognized by VB6. I beleive the functions are API functions like SysAllocStringByteLen and data types like VBGUID. I think there may be some declaration statements missing. Is the additional code available so the dll compiles without error?


Kanati(Posted 2004) [#11]
oh I'm buying this RIGHT NOW..........


Kanati(Posted 2004) [#12]
...And I did. 28 dollars is more than worth it to create a true DLL with exportable functions from VB6. Now it looks like I'm gonna have to go back and rewrite the BlitzPrinter Userlib one more time.

Kanati


augGa(Posted 2004) [#13]
@JOSCH
SysallocStringByteLen is included with vbAdvance in vbadvance.tlb .. in your vb project add reference (project/references) to vbAdance...sorry..should have included in above.. you can then see the refs using object browser...Note: you need to bring down vbAdance and install.. It is FREE to try...

@Kanati..
I agree.. I added context vb PopUp menus to my B3d app..25 mins. work... heavenly..

if You both get an example working ..plse post with the OS/Hardware you are using..so I know which (98/Me/2000/XP) seem to work ok.. I am using XP Pro..on an eT1855 ,128M devel mch.


Kanati(Posted 2004) [#14]
Kurtz and I have been playing with this thing and...

It works. Kinda. Mostly. Sometimes. :)

There's still some issues.

A) Blitz+ flat out crashes on things that Blitz3D responds with intelligent errors (ok, Unhandled Exception isn't exactly intelligent, but it's better than a GPF in blitzcc.exe.)
B) It appears that plain-jane-vanilla VB works fine but when you start accessing other objects (printer, clipboard, etc) then you start running into some problems. And I'm guessing it's because those objects are also COM objects and aren't getting initialized correctly, but I haven't yet tracked it down that far.

So while I still think this tool is well worth the 28 dollars they are charging... I recommend it with some reservations.

Kanati


Kanati(Posted 2004) [#15]
Ok... let me revise this...

A) is still valid. Blitz+ internal error checking kinda sucks.

B) COM objects can be used just fine. But you cannot call them the same as the code above demonstrates. You need to call the InitVBEngine() and immediately Cleanup(). ONCE. That's all you need to do it. After that you can call com objects all you want so far as I can ascertain currently.

So my reservations about recommending it are starting to disappear ever so slowly. The docs definitely need a bit of work though. A lot of this is becoming trial and error.

Kanati
estout@...


Kanati(Posted 2004) [#16]
Another update...

Simply moving the decls and dll to another machine results in crashing. I'm not so sure this is going to work out. I'm confused at the very least. :/

Kanati

[edit] I just noticed that I'm running 1.37 of blitz+ here and THINK I was running 1.11 on the other machine. That might have something to do with it.

[edit] Oh... and I was running on Win2000 and now I'm on XP... Recompiling doesn't work. Can't seem to get it to work period now................................


AbbaRue(Posted 2004) [#17]
Keeping all this in mind, I suppose dlls written in MASM32 could also be incorperated into Blitz3D.
Anyone given that a try yet?


augGa(Posted 2004) [#18]
@Kanati
Rem Windows requires DLLs to be registered...I moved our test rtns to my other mch (Sony Viao w/2000).. used msft Install to package it.. ran ok...


Kanati(Posted 2004) [#19]
@AbbaRue
I don't do ASM on x86 machines. Never bothered to learn. I can look at it and understand on a basic level what it's doing, but I couldn't create something from scratch. In theory of course MASM could indeed be used to create DLLs for blitz. I don't know anyone that has done so though.

@Kurtz
I didn't have a problem with registering the dll. Being a real dll it really shouldn't require it and that IS the case on a 2000 machine. But just to test, I went ahead and tested the dll you sent me after registering it on Windows XP Pro. The program dies as soon as it tries to access any dll functionality. Even the simple string and integer functions. This is something totally different going on here. I am waiting on a response from the vbadvance tech support as to any known issues with WinXP and I'll keep you informed.

Kanati


Kanati(Posted 2004) [#20]
I was unaware that VB automagically registers dll's upon compile. So they ARE getting registered. So that's the source of a few crashes I'm sure. But not all. I'm going to compile on XP from now on and test on other OS' to make sure it works.

These dll's will need an install which I really didn't want to do if I didn't have to since the end user will have to have the dll registered as well, but it's a small price to pay for the flexibility that VB gives compared to purebasic and powerbasic. Not to mention C++.

Kanati


semar(Posted 2004) [#21]
@Kanati,
I *guess* it is also possible to register the dll from within a blitz program, by calling the appropriate API - don't recall which one, but if you dig in the API world I'm sure you will find it.

I don't know if it would work though; registering a dll from within the program who makes use of it, while the program itself is already running.. hum....

Another solution is to use an installer - like installshield for example - which will install the game and eventually register the requested dlls.

Please keep on this interesting job m8 !

Regards,
Sergio.


Craig Watson(Posted 2004) [#22]
A quick call to regsvr32.exe shouldn't be too hard, right?

Would it work though?


LostCargo(Posted 2004) [#23]
regsvr32 called from a batch file setup.bat would work. just make sure u have the dlls saved in the right spot first. Also most applications will look for the dll in the same directory then in the windows/system directory next. Having the dlls in the same directory as the exe might save u from having to register them at all.


Kanati(Posted 2004) [#24]
There's a way to register a dll upon creation of the thread... It's described in the vbadvance samples... but it's really a moot point. You should just include the requirements and crate an installer for the dll. Then when you distribute the blitz program/game then you also create an installer that will register the dll.

I've run into another snag with the blitz printer userlib too... For some as yet unknown reason, after the printer dialog is released, the dll resets the printer back to the default. If I don't get that figured soon then it might not be worth pursuing for a printer userlib without creating my own printer dialog. Which I really don't want to do. Printer dialogs that aren't the system dialog tend to look........ cheap.

Kanati


augGa(Posted 2004) [#25]
@Semar--Glad to see u back Sergio... I have some pretty good luck with it.. Kanati is becoming the resident expert..(smart guy)...Rcvd the following from The developer of vbAdvance (Pete)...sounds like he is willing to assist...With all u bright folks working with this I think I will go 'back to sleep..' Got Speech working with Msagents (Sapi4) and Sapi5 on XPpro..
Little guy (Merlin) pops up and tells me where my mouse is when I right click..geez..I have too much time on my hands...

Email From Pete:
Hi Eric,

I've managed to eliminate the registration requirement for
standard DLLs created with vbAdvance. Not only that, but
the new release adds support for DllMain. This means the
runtime initialization can happen in DllMain, which is
called automatically when the DLL is loaded by Blitz.

This completely removes the runtime initialization code
requirements from your exports, which is not only simpler
for you, but also much more efficient from a performance
perspective.

If you and/or Marv Kurtz would like to try a beta copy of
the new release to test this out, just say the word and
I'll send you the download link.

Best,
Pete


Kanati(Posted 2004) [#26]
heh... definitely not a resident expert... but I'm certainly pouring some time into it. :)

I've figured a way around the whole printer dialog issue I was having. Had to do some direct API calling to do it but I think it's gonna work fine now. First time I've thought that since starting the printer userlib in vb. :)

Now I just gotta convince the "small code is the only way to go" crowd that 1.8 meg for the userlib isn't too large. I think the featureset I'm tossing into this thing might win em over though. :)

Kanati


Zace(Posted 2004) [#27]
Arghhh - i followed this letter for letter and get an error trying to make the DLL saying that the function/sub MessageBox is not found!!!

Any ideas as to what I'm doing worng ? Im using VB6sp5.


StOrM3(Posted 2004) [#28]
Kurtz can you email me your database example code, I want to use access to store my game highscores and inventory etc.. Any code you can email me showing how to do it would be greatly appreciated.

storm3@... Thanks!

Ken


Kanati(Posted 2004) [#29]
haven't heard from kurtz in a while... but I'm nearly finished with an ADO dll I plan to sell for a measly 10 bux.

If you are interested lemme know.