All BASIC

BASIC Developer & Support Resources => Compilers => Topic started by: JRS on September 09, 2010, 12:52:05 AM

Title: Calling the Oxygen DLL
Post by: JRS 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
Title: Re: Calling the Oxygen DLL
Post by: cevpegge 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
Title: Re: Calling the Oxygen DLL
Post by: JRS 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.

Title: Re: Calling the Oxygen DLL
Post by: JRS 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
Title: Re: Calling the Oxygen DLL
Post by: cevpegge 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


Title: Re: Calling the Oxygen DLL
Post by: cevpegge 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
Title: Re: Calling the Oxygen DLL
Post by: JRS 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?

Title: Re: Calling the Oxygen DLL
Post by: cevpegge 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
Title: Re: Calling the Oxygen DLL
Post by: JRS 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.

Title: Re: Calling the Oxygen DLL
Post by: JRS 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.

Title: Re: Calling the Oxygen DLL
Post by: JRS 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.

(http://files.allbasic.info/O2/o2greet.png)

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?
Title: Re: Calling the Oxygen DLL
Post by: cevpegge 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
Title: Re: Calling the Oxygen DLL
Post by: JRS 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.
Title: Re: Calling the Oxygen DLL
Post by: cevpegge 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
Title: Re: Calling the Oxygen DLL
Post by: JRS on September 10, 2010, 10:41:08 PM
(http://files.allbasic.info/O2/o2greetsb.png)

(http://files.allbasic.info/O2/congreeto2.png)

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

Now all we need to show is FreeBasic embedding ScriptBasic which embeds Oxygen.  ::)
Title: Re: Calling the Oxygen DLL
Post by: cevpegge on September 10, 2010, 10:51:47 PM
 ;D

Okay. I'll go ahead and develop this interface for JIT compiling.

Dawn breaks. I must get some sleep.

Charles
Title: Re: Calling the Oxygen DLL
Post by: JRS on September 10, 2010, 11:04:48 PM
That's great Charles!

Sure is going to open up a world of possibilities for the Windows version of SB.


BTW Are you going to be creating that O2.DLL extension module using Oxygen? If that's possible, creating extension modules for SB will be much easier then using C.
Title: Re: Calling the Oxygen DLL
Post by: cevpegge on September 11, 2010, 03:36:24 AM

Yes making extension modules should be very easy once we crack all those macros. Strictly speaking they create a dependency on compiling with C. All the extension modules are expected to be recompiled whenever the module extension interface is altered.

We have to break that rule and maybe do some reverse engineering on the macros. They seem to be more than the usual header file stuff.

Charles
Title: Re: Calling the Oxygen DLL
Post by: JRS on September 11, 2010, 09:44:38 AM
Peter's use of macros was to simulate a object like API interface. A set of helpers if you may but has been a turnoff to programmers offering to help. I would be happy if a clean, easy to use interface to O2 was the end goal. (even if the O2 extension module interface is compiled with C)  Taking on converting all those macros is a huge task just to make creating extension modules easier.. IMHO
 
Title: Re: Calling the Oxygen DLL
Post by: JRS on September 11, 2010, 06:32:03 PM
Another idea is to run O2 in a thread (like how sbhttpd works now) and use the already existing MT shared memory model. MT has locking for both read/write common variables and can even maintain session variables between iterations. Is O2 thread safe?

SB Thread Support API (http://www.scriptbasic.org/docs/dg/devguide_2.14.html)

MT Shared Variable/Session Management Extension Module (http://www.scriptbasic.org/docs/mt/mod_mt_toc.html)

Looking over the developer docs for the interpreter architecture, it seems the thread support functions are part of the scripting engine API. The best way to go might be to used scriba as a base and create a new variation SB02 that seamlessly allows creating O2 threads with shared memory support.

I could simulate this now by using sbhttpd as a local application server. (running as a Windows service) I could use the startup optional program to act as a master and send GET requests via a socket to start a SB threaded script that has O2 embedded.
Title: Re: Calling the Oxygen DLL
Post by: cevpegge on September 11, 2010, 10:59:14 PM

We could try something fairly naive to start with.

Nearly all the Oxygen runtime functions are re-entrant and use stack variables. I suppose that makes them suitable for multithreading. You can run several binaries in different threads - and each would have their own private static space as well as stack locals.  But I don't think you would be able to compile several programs at the same time. (Not that you would need to :) )

Charles
Title: Re: Calling the Oxygen DLL
Post by: JRS on September 11, 2010, 11:03:08 PM
Quote
But I don't think you would be able to compile several programs at the same time. (Not that you would need to)

Are you saying that SB could only run .exe based O2 programs in a thread and using JIT from a string is not possible?

Title: Re: Calling the Oxygen DLL
Post by: AIR on September 11, 2010, 11:11:45 PM
The following worked for me, using v3 of Scriptbasic (32bit) under Win7-64:

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

'ScriptBasic

import "c:/scriptbasic32/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?
'TRY THIS
e=dyc::dyc("ms,i,OXYGEN.DLL,o2_error,C")
'e=0
if e=0 then
  dyc::dyc("ms,i,OXYGEN.DLL,o2_exec,L",0)
endif

Regarding strings, have you tried returning a POINTER by specifying "P" as the return type?  Not sure it it would work, but I'm just saying.....

A.
Title: Re: Calling the Oxygen DLL
Post by: JRS on September 11, 2010, 11:32:58 PM
I still get a beep when I run your version under v3. Can you zip up and e-mail your v3 scriba.exe to test here?

Quote
z specifies that the argument is a pointer that should point to a zero terminated string. The BASIC argument is converted to string and a pointer to the start of the string is passed as actual argument. Note that BASIC strings are not zero terminated and the function dyc does not append the terminating zero character to the string. Thus you have to append a zero character to the BASIC string before you pass it as zero terminated string.

What do you think of using the z argument type using a CHR(0) for the argument value? (zstring with a null value)

Update - (e-mail from AIR)

Code: [Select]
e=dyc::dyc("ms,i,OXYGEN.DLL,o2_error,C")

From the interface.c file:

            case 'c': case 'C': //char
              Parm[i].nWidth  = 1;
              Parm[i].dwFlags = 0;
              if( NULL == Argument ){
                Parm[i].dwArg = 0;
                }else
                switch( TYPE(Argument) ){
                  case VTYPE_STRING:
                    if( STRLEN(Argument) < 1 )
                      Parm[i].dwArg = 0;
                    else
                      Parm[i].dwArg = *STRINGVALUE(Argument);
                    break;
                  case VTYPE_UNDEF:
                  case VTYPE_LONG:
                  case VTYPE_DOUBLE: Parm[i].dwArg = (char)besGETLONGVALUE(Argument); break;
                  default: return COMMAND_ERROR_ARGUMENT_RANGE;
                  }

With no argument, nothing extra should be passed.  It worked fine for me user 3.0

A.

Title: Re: Calling the Oxygen DLL
Post by: JRS on September 11, 2010, 11:47:41 PM
Quote
Regarding strings, have you tried returning a POINTER by specifying "P" as the return type?  Not sure it it would work, but I'm just saying.....

I think I tried P and L as return types and the same numeric value is returned as I.

It's times like this when I wish there was a PEEK/POKE function call in the NT extension module.  :'(

Title: Re: Calling the Oxygen DLL
Post by: AIR on September 11, 2010, 11:51:47 PM
I think "Z" will still place something extra on the stack.

Unless you're talking about the return type, which glancing at the code doesn't exist:

Code: [Select]
      case 1: // define the return value using a single character
        if( cbFormat < 1 )return COMMAND_ERROR_ARGUMENT_TYPE;
        cRet = tolower(*pszFormat);
        switch( cRet ){
          case 'I': case 'i': nRetSiz = sizeof(int);    break;
          case 'L': case 'l': nRetSiz = sizeof(long);   break;
          case 'P': case 'p': nRetSiz = sizeof(void *); break;
          case 'F': case 'f': nRetSiz = sizeof(float);  break;
          case 'D': case 'd': nRetSiz = sizeof(double); break;
          case 'V': case 'v': nRetSiz = sizeof(__int64);break;
          default: return COMMAND_ERROR_ARGUMENT_RANGE;
          }

I'm using the standard v3, nothing special.  What may be different is that I don't have extra items in my system or user paths by default.  I run various scripts to set my environments for SB, MinGW, Python, Ruby, etc as needed to avoid potential problems or to use different versions without conflicts.


A.
Title: Re: Calling the Oxygen DLL
Post by: AIR on September 11, 2010, 11:55:15 PM
Quote
Regarding strings, have you tried returning a POINTER by specifying "P" as the return type?  Not sure it it would work, but I'm just saying.....

I think I tried P and L as return types and the same numeric value is returned as I.

It's times like this when I wish there was a PEEK/POKE function call in the NT extension module.  :'(



I think that's because the return value is the address and not the content.
Title: Re: Calling the Oxygen DLL
Post by: JRS on September 11, 2010, 11:58:56 PM
I'm confused then.

I have two directories in my C:\ root.

C:\scriptbasic_2.1
C:\scriptbasic_3.0

All my paths and registry settings are based on ...

C:\scriptbasic

I just rename the _2.1 or _3.0 to C:\scriptbasic and go. the 2.1 version works and the 3.0 doesn't.

C:\scriptbasic\test>scriba -v
ScriptBasic v3.0
Variation >>STANDARD<< build 1
Magic value 859002680
Node size is 16
Extension interface version is 11
Compilation: Jul 18 2010 12:51:07
Executable: C:\scriptbasic\bin\scriba.exe

Just ran the same thing on my laptop and 3.0 doesn't run there either while 2.1 runs fine.

Are we running the same builds?

Update

For grins I copied the v3 scriba to my 2.1 C:\scriptbasic\bin and no joy. (BEEP)
Title: Re: Calling the Oxygen DLL
Post by: AIR on September 12, 2010, 12:28:54 AM
C:\scriptbasic32\Oxygen>scriba -v
ScriptBasic v3.0
Variation >>STANDARD<< build 1
Magic value 859002673
Node size is 16
Extension interface version is 11
Compilation: Jul 11 2010 20:06:51
Executable: C:\scriptbasic32\bin\scriba.exe

Attached is my version.

The only other difference is that I have the Oxygen.dll in the same location as the test file.  That, and I don't use a scriba.conf file.
Title: Re: Calling the Oxygen DLL
Post by: JRS on September 12, 2010, 12:39:51 AM
Thank You !

Your v3 scriba.exe works (July 11, 2010) and my v3 (July 18, 2010) doesn't.

I'll check what version is on the SB forum in the download section.

This drove me NUTS !

I may be wrong but wasn't that July 18th build an experiment of dropping the pthread reference in the build?

Title: Re: Calling the Oxygen DLL
Post by: AIR on September 12, 2010, 12:43:57 AM
Glad that worked.

I have a question:  you're trying to return strings from the DLL calls, but are they _supposed_ to be returning strings?
Title: Re: Calling the Oxygen DLL
Post by: JRS on September 12, 2010, 01:00:06 AM
Quote
I have a question:  you're trying to return strings from the DLL calls, but are they _supposed_ to be returning strings?

There are two o2 error functions.

o2_error() which I assume returns a error message string

o2_errno() that should return a error number

I only get a numeric representation of an address (both functions) if the script has syntax errors.

P.S.

See my last message about where I think the July 18th build came from.
Title: Re: Calling the Oxygen DLL
Post by: AIR on September 12, 2010, 01:04:48 AM
Quote
I have a question:  you're trying to return strings from the DLL calls, but are they _supposed_ to be returning strings?

There are two o2 error functions.

o2_error() which I assume returns a error message string

o2_errno() that should return a error number

I only get a numeric representation of an address (both functions) if the script has syntax errors.


I think o2_error returns a number, based on this:
Code: [Select]
e=dyc::dyc("ms,i,OXYGEN.DLL,o2_error,C")
'e=0
if e=0 then
Title: Re: Calling the Oxygen DLL
Post by: JRS on September 12, 2010, 01:08:58 AM
Quote from: SB DYC Docs
Xr RETURN VALUE

The return value should be specified using a single character. This can be:

i or I int, l or L long, p or P pointer, f or F float, d or D for double or v or V for __int64.

The int and long types are converted to a BASIC integer number, which is stored as a long in ScriptBasic. float and double values are returned as real number, which is stored as double in ScriptBasic. A pointer value is converted to long and is returned in an integer value. An __int64 value is returned as an 8 byte string copiing the bytes of the original __int64 value to the bytes of the BASIC string.

Looks like a number is all that is returned.
Title: Re: Calling the Oxygen DLL
Post by: JRS on September 12, 2010, 01:23:07 AM
Code: [Select]
'---------------------------------
'USING OXYGEN WITH SCRIPTBASIC DYC
'---------------------------------

DECLARE SUB DLL ALIAS "dyc" LIB "dyc"

src = """
  print "Greetings from OxygenBasic!"
""" & CHR(0)

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

e = DLL("ms,i,OXYGEN.DLL,o2_error,C")

IF e = 0 THEN
  DLL "ms,i,OXYGEN.DLL,o2_exec,L", 0
END IF

This format works for me.

DYC Documentation (http://www.scriptbasic.org/forum/index.php/topic,105.0.html)
Title: Re: Calling the Oxygen DLL
Post by: cevpegge on September 12, 2010, 02:52:20 AM

o2_errno returns an integer of value 0 if the compilation was successful

o2_error returns a pointer to a Zstring describing the error. If there is no error then the string is empty.

Neither of these expect any arguments and will not clear them from the stack. When there is a Linux version (with CDecl calling), this will not be a problem since the caller performs the stack cleanup.

Anyway the SBO2 solution will allow us 2 way traffic using string pointer arguments.

Charles
Title: Re: Calling the Oxygen DLL
Post by: verhas on September 12, 2010, 03:01:51 AM
From my point of view the macros are there to easy the creation of an extension module in C. I never intended to extend ScriptBasic in any other language than C, but it is possible if you can provide C calling interface.

If there is an extension module that uses a certain version of the interface that ScriptBasic provides towards extension modules then it should work with the next version of the interface. If it does not it means that somebody was creating the interface against the design principles. All modules should negotiate the module interface version as described in:

http://www.scriptbasic.com/html/texi/devguide/devguide_4.2.html

The only file you have to look at is basext.c All the macros are defined here.
Title: Re: Calling the Oxygen DLL
Post by: cevpegge on September 12, 2010, 06:38:47 AM

Hi Peter,

Thank you for the info.

If the fundamental interface does not change over time very much then it would be easier for other languages to port from  the C function headers directly.

Oxygen has a basic understanding of C headers but does not cover C in its entirety. (yet! :) )

Charles
Title: Re: Calling the Oxygen DLL
Post by: JRS on September 12, 2010, 02:42:09 PM
Quote
Anyway the SBO2 solution will allow us 2 way traffic using string pointer arguments.

Is your direction at this point to create an extension module (SBO2.DLL) and will act as interface for variable sharing?

I assume if your going to use the extension module API rather then the embedding API then multi-threading O2 may be a future option. (SBO2.EXE)

Let me know if there is anything I can do to help with this project.

Title: Re: Calling the Oxygen DLL
Post by: cevpegge on September 12, 2010, 03:37:43 PM
John,

I thought of testing the concept first with the the DYC / SBO2 linkage and then think about making SBO2 an extension module.

Multithreading will be important for running Windows to avoid having to break out of the Windows message loop to service ScriptBasic.

Charles
Title: Re: Calling the Oxygen DLL
Post by: JRS on September 12, 2010, 04:39:16 PM
Sounds like a great plan.

I'm really excited about this project and hope other Basic languages take note of the advantages of having an embeddable JIT compiler at their disposal.
Title: Re: Calling the Oxygen DLL
Post by: cevpegge on September 15, 2010, 11:45:56 PM

John,

I'm making progress. I've included a folder for ScriptBasic in the examples. SBO2. We can now compile and run O2 scripts through ScriptBasic using DYC and SBO2.

For SBdemo3, The relative paths of the folders should be maintained so that the graphics library can be located. Oxygen also required a minor addition to aid relative path mapping.


SBO2demo3.sb
Code: [Select]
'---------------------------------
'USING SBO2 WITH SCRIPTBASIC DYC
'---------------------------------

'ScriptBasic

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
'------------------

send="""

  basic
  #include PortViewer2.o2bas

""" & chr$(0)

bufferlength=1000
receive=space(bufferlength)

replylength=dyc::dyc("ms,i,sbo2.dll,run,ZZL",send,receive,bufferlength)

'print replylength
'print left(receive,replylength)
'line input w

SBO2.DLL
Code: [Select]
basic

  #file "sbo2.dll"

  library "oxygen.dll"

  declare sub      o2_asmo  (byval s as string)
  declare sub      o2_basic (byval s as string)
  declare function o2_buf   (byval n as long) as long
  declare function o2_errno () as long
  declare function o2_error () as string
  declare function o2_exec  (optional byval p as long) as long
  declare function o2_get   () as string
  declare function o2_len   () as long
  declare function o2_prep  (byval srcBSTR as string) as string
  declare sub      o2_put   (byval c as string)
  declare function o2_view  (byval srcBSTR as string) as string

  library ""



  '----------------------------------------------------------------------
  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



  '------------------------------------------------------------------
  function run(sys send, sys receive, sys bufferlength) as sys export
  '==================================================================
  '
  zstring * z : &z=send
  string c=z
  string s=""
  o2_asmo c
  if o2_errno then
    s=o2_error
  else
    o2_exec
    s="Okay"
  end if
  '
  replylength=len s
  if replylength>bufferlength then replylength=bufferlength
  copy receive, *s, replylength
  return replylength
  end function

Charles

Alpha006
https://sourceforge.net/projects/oxygenbasic/files/

Title: Re: Calling the Oxygen DLL
Post by: JRS on September 16, 2010, 12:05:22 AM
I didn't think I was going to hear from you for awhile. (working on compiler)

I tried to download the Alpha06 (twice) and it said the zip file is bad.

Looking forward to playing with this.

Title: Re: Calling the Oxygen DLL
Post by: cevpegge on September 16, 2010, 12:27:09 AM

I checked the download and the zip works correctly. Is this Mr Kapersky interfering again?

On Vista, there are the usual security questions about running new software, and the manual has to be unblocked - (going into properties). But otherwise no problems here.

Charles
Title: Re: Calling the Oxygen DLL
Post by: JRS on September 16, 2010, 12:52:39 AM
Quote
I checked the download and the zip works correctly. Is this Mr Kapersky interfering again?

I'm able to unzip all your previous zips, just Alpha06 pops a dialog in PowerArchiever saying the zip has an error then exits.

It's Alpha05 Mr. Kaspersky doesn't like (false positive e-mail virus/worm) and makes me deleted your files.
Title: Re: Calling the Oxygen DLL
Post by: cevpegge on September 16, 2010, 01:04:54 AM
I've create a new zip and uploaded it. Let's hope this this one works!

Charles
Title: Re: Calling the Oxygen DLL
Post by: JRS on September 16, 2010, 01:20:30 AM
I was able to unzip the archive this time but still having Mr. Kaspersky issues.
Title: Re: Calling the Oxygen DLL
Post by: cevpegge on September 16, 2010, 01:30:58 AM

eo2.exe is not on your Kapersky list. That's interesting because it is very similar to co2 and cco2. The main difference being it executes a program directly instead of making a PE file.

Charles
Title: Re: Calling the Oxygen DLL
Post by: JRS on September 16, 2010, 01:46:48 AM
I think your on to something.

 
Title: Re: Calling the Oxygen DLL
Post by: cevpegge on September 16, 2010, 02:16:09 AM
With eo2.exe surviving, you should be able to run most of the the examples from the Scit IDE (F5 key).

Charles

PS:

SBO2.DLL also survived :)

I have sent eo2 co2 and cco2 to Mr Kapersky's Lab for testing.