Visual Basic DLL- It Does Work
Blitz3D Forums/Blitz3D Beginners Area/Visual Basic DLL- It Does Work
| ||
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 |
| ||
@Kurtz, Thanks a lot m8 ! :) Sergio. |
| ||
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 |
| ||
Great that it can be done, and I'm sure there are good reasons for doing it, but, what are they? |
| ||
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.... |
| ||
I suspected database stuff might come into it. Thanks for your explanation. |
| ||
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... |
| ||
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? |
| ||
@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 ... |
| ||
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? |
| ||
oh I'm buying this RIGHT NOW.......... |
| ||
...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 |
| ||
@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. |
| ||
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 |
| ||
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@... |
| ||
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................................ |
| ||
Keeping all this in mind, I suppose dlls written in MASM32 could also be incorperated into Blitz3D. Anyone given that a try yet? |
| ||
@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... |
| ||
@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 |
| ||
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 |
| ||
@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. |
| ||
A quick call to regsvr32.exe shouldn't be too hard, right? Would it work though? |
| ||
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. |
| ||
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 |
| ||
@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 |
| ||
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 |
| ||
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. |
| ||
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 |
| ||
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. |