Page 1 of 2

call to POWERBASIC dll

Posted: Fri Jun 09, 2017 7:53 pm
by williamvanhoecke
Hello, I am new to PureBasic.

I have this dll written in PowerBasic, and I need to call it in PureBasic, but it giving me some trouble.
I found a tip to correct this.... call with type BSTR.
OK so far but....

Then the dll returns a string but i can't define a Prototype.p-bstr
A solution would be to change the return value to WSTRING....but that I can't change the export to WSTRING (if I do the native powerbasic program that calls the dll does not work correctly)

So I realy need a solution without making changes to the original dll.

Anyone with some tips ????


POWERBASIC dll source

Code: Select all

#COMPILE DLL "scrambler.dll"
#DIM ALL
'--------------------------------------------------------------------------------------------------------------------------------------------------------------
FUNCTION SCRAMBLE(t AS STRING,sd AS LONG) EXPORT AS STRING
  LOCAL tmp1&,scrambled$,s&,ln&,x&,v1$,v2$
  RANDOMIZE sd
  REPLACE ANY "|" WITH "!" IN t
  t = REMOVE$(t, ANY CHR$(0))
  ln& = LEN(t)
  scrambled$ = STRING$(ln&,"|")
  FOR tmp1& = 1 TO ln&
    DO : s&=RND(1,ln&): LOOP WHILE MID$(t,s&,1) = "|"
    x&=RND(1,255)
    MID$(scrambled$,tmp1&,1) = CHR$(ASC(MID$(t,s&,1))XOR x&)
    MID$(t,s&,1) = "|"
  NEXT tmp1&
  SCRAMBLE = scrambled$
END FUNCTION

'--------------------------------------------------------------------------------------------------------------------------------------------------------------
FUNCTION UNSCRAMBLE(t AS STRING,sd AS LONG) EXPORT AS STRING
  LOCAL tmp1&,unscrambled$,s&,ln&,x&,v1$,v2$
  RANDOMIZE sd
  ln& = LEN(t)
  unscrambled$=STRING$(ln&,"|")
  FOR tmp1& = 1 TO ln&
    DO: s&=RND(1,ln&): LOOP WHILE MID$(unscrambled$,s&,1) <> "|"
    x&=RND(1,255)
    MID$(unscrambled$,s&,1) = CHR$(ASC(MID$(t,tmp1&,1))XOR x&)
    MID$(t,tmp1&,1) = "|"
  NEXT tmp1&
  UNSCRAMBLE = unscrambled$
END FUNCTION


PUREBASIC call

Code: Select all

OpenLibrary(0,"scrambler.dll")
   Prototype.L ProtoFunction(Txt.p-bstr, Sd.l)
   SCRAMBLE.ProtoFunction=GetFunction(0, "SCRAMBLE")
   UNSCRAMBLE.ProtoFunction=GetFunction(0, "UNSCRAMBLE") 
   Td.s = SCRAMBLE("abcdefghijklmnopqrstuvwxyzABCEDEGHIJKLMNOPQRSTUVWXYZ",93235) ;---> error because function rreturns a number ????? 
  ;Td.s = PEEKS(SCRAMBLE("abcdefghijklmnopqrstuvwxyzABCEDEGHIJKLMNOPQRSTUVWXYZ",93235)) ;---> error: invalid memory access 
CloseLibrary(0)

Re: call to POWERBASIC dll

Posted: Fri Jun 09, 2017 10:30 pm
by netmaestro
Try:

Code: Select all

this$ = Peeks(Scramble(that$, num), -1, #PB_Unicode)
debug this$

Re: call to POWERBASIC dll

Posted: Mon Jun 12, 2017 10:33 pm
by williamvanhoecke
Hi netmaestro,
Thnks for the sugestion, but it still does'nt work,

Code: Select all

td.s = PeekS(SCRAMBLE("abcdefghijklmnopqrstuvwxyzABCEDEGHIJKLMNOPQRSTUVWXYZ",93235), -1, #PB_Unicode)
still giving

[23:28:52] Waiting for executable to start...
[23:28:52] Executable type: Windows - x86 (32bit, Unicode, Thread)
[23:28:52] Executable started.
[23:28:53] [ERROR] Main.pb (Line: 347)
[23:28:53] [ERROR] Invalid memory access. (read error at address 6422620)
[23:29:16] The Program was killed.

Re: call to POWERBASIC dll

Posted: Mon Jun 12, 2017 11:20 pm
by jack
pardon me if am totally off, but doesn't PowerBasic have zstring ? if so give that a try.

Re: call to POWERBASIC dll

Posted: Mon Jun 12, 2017 11:23 pm
by netmaestro
Try PeekS(<address>) alone or #PB_Ascii instead if Unicode.

Re: call to POWERBASIC dll

Posted: Mon Jun 12, 2017 11:25 pm
by Fig

Re: call to POWERBASIC dll

Posted: Tue Jun 13, 2017 8:37 pm
by williamvanhoecke
Thanks guys, but no luck so far

@jack: no... seems to be BSTR

@netmaestro, @Fig: It's not the PeekS but the actual call to the DLL that gives the ERROR

I changed the code to seperate the CALL and the PeekS.... The call fails
I also added a function FILEWRITE that receives NO parameters but RETURNS a string..... THIS WORKS OK !!!!!!

I am very puzzled about this simple DLL call.... and I haven't started calling system API's yet

Code: Select all

Ts.s = "abcdefghijklmnopqrstuvwxyzABCEDEGHIJKLMNOPQRSTUVWXYZ"
Td.s = ""
R.l
Sd.l = 93235

OpenLibrary(0,"scrambler.dll")
    Prototype.L ProtoFunction1(Txt.p-bstr, Sd.l)
    Prototype.L ProtoFunction2()
    SCRAMBLE.ProtoFunction1=GetFunction(0, "SCRAMBLE")
    UNSCRAMBLE.ProtoFunction1=GetFunction(0, "UNSCRAMBLE") 
    FILEWRITE.ProtoFunction2=GetFunction(0, "FILEWRITE")

    R = FILEWRITE()                   ;------> Works fine ?????
    Td = PeekS(R,-1,#PB_Ascii)

    R = SCRAMBLE(Ts,93235)       ;------> [21:14:18] [ERROR] Main.pb (Line: 351) Invalid memory access. (read error at address 6463488)  
    Td = PeekS(R,-1,#PB_Ascii)

  CloseLibrary(0) 
PowerBasic source of the DLL

Code: Select all

FUNCTION FILEWRITE() EXPORT AS STRING
  OPEN "c:\Users\William\Google Drive\BAS_PUREBASIC\LISTRIK\testfile.txt" FOR OUTPUT AS #9
  PRINT #9,"Yoohoo"
  CLOSE #9
  IF ERR THEN
      FILEWRITE = STR$(ERR)
  ELSE
      FILEWRITE = "abcdefghijklmnopqrstuvwxyzABCEDEGHIJKLMNOPQRSTUVWXYZ"
  END IF
END FUNCTION

'--------------------------------------------------------------------------------------------------------------------------------------------------------------
FUNCTION SCRAMBLE(t AS STRING,sd AS LONG) EXPORT AS STRING
  LOCAL tmp1&,scrambled$,s&,ln&,x&,v1$,v2$
  RANDOMIZE sd
  REPLACE ANY "|" WITH "!" IN t
  t = REMOVE$(t, ANY CHR$(0))
  ln& = LEN(t)
  scrambled$ = STRING$(ln&,"|")
  FOR tmp1& = 1 TO ln&
    DO : s&=RND(1,ln&): LOOP WHILE MID$(t,s&,1) = "|"
    x&=RND(1,255)
    MID$(scrambled$,tmp1&,1) = CHR$(ASC(MID$(t,s&,1))XOR x&)
    MID$(t,s&,1) = "|"
  NEXT tmp1&
  SCRAMBLE = scrambled$
END FUNCTION

'--------------------------------------------------------------------------------------------------------------------------------------------------------------
FUNCTION UNSCRAMBLE(t AS STRING,sd AS LONG) EXPORT AS STRING
  LOCAL tmp1&,unscrambled$,s&,ln&,x&,v1$,v2$
  RANDOMIZE sd
  ln& = LEN(t)
  unscrambled$=STRING$(ln&,"|")
  FOR tmp1& = 1 TO ln&
    DO: s&=RND(1,ln&): LOOP WHILE MID$(unscrambled$,s&,1) <> "|"
    x&=RND(1,255)
    MID$(unscrambled$,s&,1) = CHR$(ASC(MID$(t,tmp1&,1))XOR x&)
    MID$(t,tmp1&,1) = "|"
  NEXT tmp1&
  UNSCRAMBLE = unscrambled$
END FUNCTION

Re: call to POWERBASIC dll

Posted: Tue Jun 13, 2017 8:45 pm
by netmaestro
Try:

Code: Select all

Prototype.L ProtoFunction(*txt, Sd.l)
And try variants of PeekS() with the result, simplest first. For the call use Scramble(@this$, num)

Re: call to POWERBASIC dll

Posted: Tue Jun 13, 2017 8:56 pm
by Fig
Just out of curiousity, i read powerbasic handle strings with a very fancy and sofisticated way. I guess that's why you absolutely want to use your own dll and dont' want to code your sub program in Purebasic instead...
What are the pro of powerbasic about strings ?

Re: call to POWERBASIC dll

Posted: Thu Jun 15, 2017 1:48 am
by williamvanhoecke
@netmaestro
Tried the pointer things too... always error

@Fig
1) True, Powerbasic has a powerfull set of stringhandling commands

2) The need to use the POWERBASIC DLL is:
Since I believe powerbasic is dead in the water I am porting a complex powerbasic app to purebasic.
Some of the datafiles produced by the powerbasic app are scrambled by the SCRAMBLE and UNSCRAMBLE routine whitch totally relies on the RANDOMIZE (seeding) and RND (genarating) functions of powerbasic.
RANDOMIZE and RND functions are program-language dependent ..... this means that IF I rewrite the SCRAMBLE - UNSCRAMBLE routine in purebasic, it will NOT be able to UNSCRAMBLE the original files SCRAMBLED by the powerbasic routine.... hence .... there is only one way.

But while this looks a fairly simple thing to do, I am not yet succeeding :( :(

Below is a link to the DLL and an APP calling the dll
Anyone cares to try and call the dll from purebasic ?

https://drive.google.com/open?id=0B4won ... khxZU9kUlU

Re: call to POWERBASIC dll

Posted: Thu Jun 15, 2017 3:54 am
by jack
can you use stringz or wstringz ?
I know they are fixed length, so it will probably not work in this case
but just as a test I suggest you try to pass a stringz to pure basic and see if it works.

Re: call to POWERBASIC dll

Posted: Thu Jun 15, 2017 9:39 am
by Fig
I come to the idea that the simplest way to handle this situation is to send only pointers between your dll and Purebasic.
So, modify your Dll to receive 3 numerical values (one pointer, two longs)
In your Dll, just make sure to concatenate your string with a powerbasic equivalent to peeks ((power basic's doc says peek$$ ??).

unfortunatly your powerbasic doesnt' have a trial/demo version so i can't make any try.

POWerBasic will be something like this: (make sure t$ is a bstring... i mean peek$$ read a wstring but t$ should handle it as a bstring ??)

Code: Select all

FUNCTION SCRAMBLE(tt AS LONG,lng as LONG,sd AS LONG) EXPORT AS STRING
  LOCAL tmp1&,scrambled$,s&,ln&,x&,v1$,v2$,t$
  RANDOMIZE sd
  t$  = PEEK$$ (WSTRINGZ , tt , lng+2)
  REPLACE ANY "|" WITH "!" IN t$
etc...
And Purebasic

Code: Select all

Ts.s = "abcdefghijklmnopqrstuvwxyzABCEDEGHIJKLMNOPQRSTUVWXYZ"
ln.l=len(Ts)
Sd.l=93235
OpenLibrary(0,"scrambler.dll")
  debug PEEKS(CALLFUNCTION(0,"SCRAMBLE" ,@Ts ,ln ,Sd),-1,#PB_ASCII)
CloseLibrary(0)
If it works, then, we will handle the length of the returned string by peeking his length...

Re: call to POWERBASIC dll

Posted: Thu Jun 15, 2017 11:33 pm
by williamvanhoecke
Hi Fig,
thanks for your effort...and your solution might work,
BUT the original DLL can't be fiddled with because it needs to UNSCRAMBLE tons of old data.

The only way is to call the dll as it is.

Still no luck .... I don't understand why it is so complicated to call such a simple dll ???

Below is a link to the DLL and a POWERBASIC APP calling the dll
Anyone cares to try and call the dll from purebasic ?

https://drive.google.com/open?id=0B4won ... khxZU9kUlU

Re: call to POWERBASIC dll

Posted: Fri Jun 16, 2017 1:58 am
by Mijikai
Seems like the dll actually needs a structure...

Working:

Code: Select all


Procedure.i CallScramble(P1.i,P2.i);no sanity checks!
  Protected Lib.i 
    Lib = OpenLibrary(#PB_Any,"scrambler.dll")
    ProcedureReturn CallFunction(Lib,"SCRAMBLE",P1,P2)
EndProcedure

Debug PeekS(CallScramble(?T,?DS),-1,#PB_Ascii)

DataSection
  DS:
  !dd 0
  T:
  Data.l ?TP
  Data.l 10
  TP:
  !db 'TestString',0
EndDataSection
If anyone else wants to investigate:

Code: Select all

SCRAMBLETEST.EXE+1272 - BB 58CA2000           - mov ebx,SCRAMBLETEST.EXE+CA58
SCRAMBLETEST.EXE+1277 - 53                    - push ebx
SCRAMBLETEST.EXE+1278 - BB 50CA2000           - mov ebx,SCRAMBLETEST.EXE+CA50
SCRAMBLETEST.EXE+127D - 53                    - push ebx
SCRAMBLETEST.EXE+127E - FF 15 6CD52000        - call dword ptr 

Re: call to POWERBASIC dll

Posted: Fri Jun 16, 2017 3:30 am
by Fig
is it because powerbasic do not produce a .lib to link the dll ? :?: