Author Topic: Calling the Oxygen DLL  (Read 19358 times)

JRS

  • Guest
Calling the Oxygen DLL
« on: September 09, 2010, 12:52:05 AM »
Charles,

I want to try using the DYC (generic DLL interface extension module) in SB to call the Oxygen JIT compiler with a program string. Can you show us an example of this?

John

cevpegge

  • Guest
Re: Calling the Oxygen DLL
« Reply #1 on: September 09, 2010, 04:46:15 AM »
Here is the Hello program John

I tested this with Oxygen.dll is the same folder as the script

Code: [Select]
'---------------------------------
'USING OXYGEN WITH SCRIPTBASIC DYC
'---------------------------------

'ScriptBasic

module dyc

'FUNCTION DECLARATIONS
 
declare sub     ::dyc alias "dyc" lib "dyc"

end module


'OXYGEN SOURCE CODE
'------------------

src="""
  print "Greetings from OxygenBasic!"

""" & chr$(0)

dyc::dyc("ms,i,OXYGEN.DLL,o2_mode,L",0)
dyc::dyc("ms,i,OXYGEN.DLL,o2_basic,Z",src)


'how do we make dll calls that have no arguments?
'e=dyc::dyc("ms,i,OXYGEN.DLL,o2_error,")
e=0
if e=0 then
  dyc::dyc("ms,i,OXYGEN.DLL,o2_exec,L",0)
endif


Some obstacles:

I would like to return error numbers and messages but DYC does not seem to support DLL calls without arguments

DYC does not seem to support returned zStrings

How do you Switch off the console?

Anyway, it's a start :)

Charles
« Last Edit: September 09, 2010, 05:33:28 AM by cevpegge »

JRS

  • Guest
Re: Calling the Oxygen DLL
« Reply #2 on: September 09, 2010, 05:10:21 PM »
Thanks Charles, that is a great start and allows me to try to figure out the issues you ran into are.

I'll let you know what I come up with.


JRS

  • Guest
Re: Calling the Oxygen DLL
« Reply #3 on: September 09, 2010, 10:54:05 PM »
Charles,

I gave your test program a try and all I get is a beep and back to the prompt. Were you able to get it to print from O2?

Code: [Select]
'---------------------------------
'USING OXYGEN WITH SCRIPTBASIC DYC
'---------------------------------

'ScriptBasic


'FUNCTION DECLARATIONS
 
declare sub dyc alias "dyc" lib "dyc"


'OXYGEN SOURCE CODE
'------------------

src="""
  print "Greetings from OxygenBasic!"

""" & CHR(0)

dyc("ms,i,OXYGEN.DLL,o2_mode,L",0)
dyc("ms,i,OXYGEN.DLL,o2_basic,Z",src)


' how do we make dll calls that have no arguments?
' e=dyc::dyc("ms,i,OXYGEN.DLL,o2_error,")
e=0
IF e=0 THEN
  dyc("ms,i,OXYGEN.DLL,o2_exec,L",0)
END IF

P.S.

I placed the OXYGEN.DLL in the same directory as this program. The strange thing is the scriba -d option isn't returning any extension module (DYC) load messages.  ???

Update

I included DYC (see below) and was able to get the -d load verification. Sooo, it looks like the only response from O2 in this demo is a beep. Correct?

C:\scriptbasic\test>scriba -d o2test2.sb
Searching installed module header file 'dyc.bas' ...
Checking installed module header file location 'c:\scriptbasic\include\dyc.bas' Result=OK
Including file 'c:\scriptbasic\include\dyc.bas'

C:\scriptbasic\test>

Code: [Select]
'---------------------------------
'USING OXYGEN WITH SCRIPTBASIC DYC
'---------------------------------

'ScriptBasic

INCLUDE dyc.bas

'OXYGEN SOURCE CODE
'------------------

src="""
  print "Greetings from OxygenBasic!"

""" & chr$(0)

dyc::dyc("ms,i,OXYGEN.DLL,o2_mode,L",0)
dyc::dyc("ms,i,OXYGEN.DLL,o2_basic,Z",src)


'how do we make dll calls that have no arguments?
'e=dyc::dyc("ms,i,OXYGEN.DLL,o2_error,")
e=0
if e=0 then
  dyc::dyc("ms,i,OXYGEN.DLL,o2_exec,L",0)
endif

Update

This is where I am with this. I think I figured out the no argument issue.

Code: [Select]
'---------------------------------
'USING OXYGEN WITH SCRIPTBASIC DYC
'---------------------------------

'ScriptBasic

INCLUDE dyc.bas

'OXYGEN SOURCE CODE
'------------------

src="""
  print "Greetings from OxygenBasic!"

""" & chr$(0)

ok = dyc::dyc("ms,i,OXYGEN.DLL,o2_mode,L",0)
PRINT "Debug 1: ",ok,"\n"
ok = dyc::dyc("ms,i,OXYGEN.DLL,o2_basic,Z",src)
PRINT "Debug 2: ",ok,"\n"

'how do we make dll calls that have no arguments?
e=dyc::dyc("ms,i,OXYGEN.DLL,o2_error,L",undef)
PRINT "Debug 3: ",e,"\n"

if e=0 then
  ok = dyc::dyc("ms,i,OXYGEN.DLL,o2_exec,L",0)
  PRINT "Debug 4: ",ok,"\n"
endif

C:\scriptbasic\test>o2test2.sb
Debug 1: 0
Debug 2: 4181568
Debug 3: 0
Debug 4: 2440708

C:\scriptbasic\test>

Update

I wanted to see if the o2_error() function was really working with my no argument guess.

Code: [Select]
'---------------------------------
'USING OXYGEN WITH SCRIPTBASIC DYC
'---------------------------------

'ScriptBasic

INCLUDE dyc.bas

'OXYGEN SOURCE CODE
'------------------

src="""
  print "Greetings from OxygenBasic!"

""" & chr$(0)

ok = dyc::dyc("ms,i,OXYGEN.DLL,o2_mode,L",0)
PRINT "Debug 1: ",ok,"\n"
ok = dyc::dyc("ms,i,OXYGEN.DLL,o2_basic,Z","printt" & chr(0))
PRINT "Debug 2: ",ok,"\n"

'how do we make dll calls that have no arguments?
e=dyc::dyc("ms,i,OXYGEN.DLL,o2_error,L",undef)
PRINT "Debug 3: ",e,"\n"

if e=0 then
  ok = dyc::dyc("ms,i,OXYGEN.DLL,o2_exec,L",0)
  PRINT "Debug 4: ",ok,"\n"
endif

C:\scriptbasic\test>o2test.sb
Debug 1: 0
Debug 2: 4160992
Debug 3: 4161176

C:\scriptbasic\test>

Update

You asked "How do you Switch off the console?" so here is my attempt. The console title changes to the name of the program running but nothing prints. (O2 or my debug PRINTs)

Code: [Select]
'---------------------------------
'USING OXYGEN WITH SCRIPTBASIC DYC
'---------------------------------

'ScriptBasic

INCLUDE dyc.bas
INCLUDE cio.bas

cio::Detach()

'OXYGEN SOURCE CODE
'------------------

src="""
  print "Greetings from OxygenBasic!"

""" & chr$(0)

ok = dyc::dyc("ms,i,OXYGEN.DLL,o2_mode,L",0)
PRINT "Debug 1: ",ok,"\n"
ok = dyc::dyc("ms,i,OXYGEN.DLL,o2_basic,Z","print \"JRS\"" & chr(0))
PRINT "Debug 2: ",ok,"\n"

'how do we make dll calls that have no arguments?
e=dyc::dyc("ms,i,OXYGEN.DLL,o2_error,L",undef)
PRINT "Debug 3: ",e,"\n"

if e=0 then
  ok = dyc::dyc("ms,i,OXYGEN.DLL,o2_exec,L",0)
  PRINT "Debug 4: ",ok,"\n"
endif

SLEEP 5
« Last Edit: September 10, 2010, 01:19:40 AM by JRS »

cevpegge

  • Guest
Re: Calling the Oxygen DLL
« Reply #4 on: September 10, 2010, 03:29:33 AM »

Hi John,

Thanks for investigating.

Detaching the console is a fair compromise. It flashes briefly on the screen at the start of the program.

I think we have differing file mappings. I am running the script from the OxygenBasic folder alongside Oxygen.dll. SB knows where the extension modules are located but not the .bas declaration files, so I put the module declarations directly into the demo script.

(I'm using Notepad++)

When the SB script is run, you may see the console flash on and off the screen then A message box should appear with the greeting.

Still no luck with o2_error. The expression you tried still pushes a Long integer onto the CPU stack causing a GPF.
I think that DYC has no provision for handling an empty argument list.


Charles

This includes Console detach:
Code: [Select]
'---------------------------------
'USING OXYGEN WITH SCRIPTBASIC DYC
'---------------------------------

'ScriptBasic


'INCLUDE cio.bas
'INCLUDE dyc.bas

module cio
  declare sub ::detach        alias "sbdetach"   lib "cio"
end module

cio::Detach()

module dyc
  declare sub     ::dyc alias "dyc" lib "dyc"
end module



'OXYGEN SOURCE CODE
'------------------

src="""
  print "Greetings from OxygenBasic!"

""" & chr$(0)

dyc::dyc("ms,i,OXYGEN.DLL,o2_mode,L",0)
dyc::dyc("ms,i,OXYGEN.DLL,o2_basic,Z",src)


'how do we make dll calls that have no arguments?
'e=dyc::dyc("ms,i,OXYGEN.DLL,o2_errno,L",undef)
e=0
if e=0 then
  dyc::dyc("ms,i,OXYGEN.DLL,o2_exec,L",0)
endif



cevpegge

  • Guest
Re: Calling the Oxygen DLL
« Reply #5 on: September 10, 2010, 03:44:18 AM »

The demo script also works in any folder on its own if you put a copy of Oxygen.dll into the scriptbasic\bin folder

Charles

JRS

  • Guest
Re: Calling the Oxygen DLL
« Reply #6 on: September 10, 2010, 10:04:29 AM »
Quote
When the SB script is run, you may see the console flash on and off the screen then A message box should appear with the greeting.

Are you saying that all O2 PRINT statement go to a message box?


cevpegge

  • Guest
Re: Calling the Oxygen DLL
« Reply #7 on: September 10, 2010, 11:00:35 AM »

Yes John, this is the default print. It is primarily used for testing and can be overridden any time.

Has the prog given you a Greeting messagebox yet?

If so, I have another demo ready for 2 way message sending. Then we can create an intermediary DLL between Oxygen and ScriptBasic.

Charles

JRS

  • Guest
Re: Calling the Oxygen DLL
« Reply #8 on: September 10, 2010, 04:20:09 PM »
Quote
Has the prog given you a Greeting messagebox yet?

Nope, just a beep from my speaker.

If a message box was being created then there would be an OKAY button to press and O2 would wait till it was pressed. (returns immediately)

What does the return values from your functions tell you? Are they pointers to error codes? SB has no ability (peek/poke/mem) at the script level to access memory or pointers. This is the extension modules responsibility.

« Last Edit: September 10, 2010, 04:21:55 PM by JRS »

JRS

  • Guest
Re: Calling the Oxygen DLL
« Reply #9 on: September 10, 2010, 05:24:32 PM »
Quote
Still no luck with o2_error. The expression you tried still pushes a Long integer onto the CPU stack causing a GPF.
I think that DYC has no provision for handling an empty argument list.

Code: [Select]
'how do we make dll calls that have no arguments?
e=dyc::dyc("ms,i,OXYGEN.DLL,o2_error,L",undef)
PRINT "Debug 3: ",e,"\n"

If I pass good script code/text to your function os_error returns a zero. If I pass bad code, I get a pointer??? returned. That leads me to believe that the undef for a argument is working. Is it possible DYC is generating a VOID pointer as an argument when using undef?

I was looking through the interface.c code for the DYC extension module and it looks like you are right about it assuming all functions have arguments. I don't know why my attempt at getting around it seems to work. I don't understand why you're getting a GPF if your using the same version of SB as I am.



FWIW I'm using the MinGW-gcc compiled version of SB for testing. DYC is from the 2.1 release.

« Last Edit: September 10, 2010, 08:11:21 PM by JRS »

JRS

  • Guest
Re: Calling the Oxygen DLL
« Reply #10 on: September 10, 2010, 09:19:55 PM »
I went back to version 2.1 of SB and it worked. The hack for the o2_errno() didn't GPF for me.



Code: [Select]
'---------------------------------
'USING OXYGEN WITH SCRIPTBASIC DYC
'---------------------------------

'ScriptBasic

declare sub detach alias "sbdetach" lib "cio"
declare sub dyc alias "dyc" lib "dyc"

' Detach()

'OXYGEN SOURCE CODE
'------------------

src="""
  print "Greetings from OxygenBasic!"

""" & chr$(0)

ok = dyc("ms,i,OXYGEN.DLL,o2_mode,L",0)
PRINT "Debug 1: ",ok,"\n"
ok = dyc("ms,i,OXYGEN.DLL,o2_basic,Z",src)
PRINT "Debug 2: ",ok,"\n"

'how do we make dll calls that have no arguments?
e=dyc("ms,i,OXYGEN.DLL,o2_errno,L",undef)
PRINT "Debug 3: ",e,"\n"

if e=0 then
  ok = dyc("ms,i,OXYGEN.DLL,o2_exec,L",0)
  PRINT "Debug 4: ",ok,"\n"
endif

C:\scriptbasic\test>o2test
Debug 1: 0
Debug 2: 3351688
Debug 3: 0
Debug 4: 1325812

C:\scriptbasic\test>

@Armando, if your lurking, any ideas why the MinGW-gcc version of scriba isn't working?
« Last Edit: September 10, 2010, 09:43:58 PM by JRS »

cevpegge

  • Guest
Re: Calling the Oxygen DLL
« Reply #11 on: September 10, 2010, 09:47:11 PM »
Excellent John!

I'm using SB_2.1_RC2_Win.

My OS is Windows Vista 64 (if that makes any difference)

In this version Scriba does not have an icon and I also had to associate sb files with scriba manually. It locates Extension modules correctly but not include/*.bas files.

with regard to o2_errno which takes no arguments, any arguments passed to it will remain on the stack. It may or may not cause a GPF later. Hard to predict.

Charles

JRS

  • Guest
Re: Calling the Oxygen DLL
« Reply #12 on: September 10, 2010, 09:59:47 PM »
Quote
It locates Extension modules correctly but not include/*.bas files.

The include path is defined in your scriba.conf file.

; where to search system and module include files
; trailing / or \\ is needed
include "c:\\scriptbasic\\include\\"

Quote
My OS is Windows Vista 64 (if that makes any difference)

I'm using XP on a P4 at the moment to test this.

Quote
In this version Scriba does not have an icon and I also had to associate sb files with scriba manually.

That was a nice feature of Peter's home brew install. It would write the registry keys. If I'm not mistaken he used scriba to do it. I need to look into that again and migrate that feature forward with Armando's update of 2.1.

Quote
with regard to o2_errno which takes no arguments, any arguments passed to it will remain on the stack. It may or may not cause a GPF later. Hard to predict.

Knowing a bit how undef is used in SB, it was worth a shot to see if I could make it work with DYC. The change to DYC to allow no argument is trivial.

cevpegge

  • Guest
Re: Calling the Oxygen DLL
« Reply #13 on: September 10, 2010, 10:15:15 PM »
Thanks John,

I will amend the scriba.conf.

We still have the problem of returning strings from Oxygen via DYC but here is the next test using an intermediary DLL

I've zipped it below. If you put a copy of Oxygen into the folder and run the sbdemo2 script, you should get an Oxygen  messagebox greeting then a returned message on the SB console.


Charles

sbdemo2.sb
Code: [Select]

'---------------------------------
'USING SBO2 WITH SCRIPTBASIC DYC
'---------------------------------

'ScriptBasic

module dyc
  declare sub     ::dyc alias "dyc" lib "dyc"
end module



'OXYGEN SOURCE CODE
'------------------

send="""
  Greetings from ScriptBasic!

""" & chr$(0)

bufferlength=1000
receive=space(bufferlength)

replylength=dyc::dyc("ms,i,sbo2.dll,message,ZZL",send,receive,bufferlength)
'print replylength
print left(receive,replylength)
line input w

sbo2.o2bas (generates sbo2.dll)
Code: [Select]
basic

#file "sbo2.dll"

'----------------------------------------------------------------------
function message(sys send, sys receive, sys bufferlength) as sys export
'======================================================================

zstring * z : &z=send
print z

s="Greetings from sbo2 oxygen!"
replylength=len s
if replylength>bufferlength then replylength=bufferlength
copy receive, *s, replylength

return replylength

end function

JRS

  • Guest
Re: Calling the Oxygen DLL
« Reply #14 on: September 10, 2010, 10:41:08 PM »




That's the way to create a DLL.  8)

Now all we need to show is FreeBasic embedding ScriptBasic which embeds Oxygen.  ::)