Reading a PowerBASIC dll

Just starting out? Need help? Post your questions and find answers here.
deltarho
New User
New User
Posts: 6
Joined: Fri Jul 06, 2012 5:52 pm

Reading a PowerBASIC dll

Post by deltarho »

I am experimenting with writing a dll in PowerBASIC and reading it from PureBasic.

Here is the PowerBASIC code

Code: Select all

#Compile DLL "PB_String_Crunches.dll"
#Dim All
 
Function RemoveAny( ByVal MainString As String, ByVal MatchString As String ) Export As String
 
  Function = Remove$( MainString, Any MatchString )
 
End Function

and here is the PureBasic code

Code: Select all

Prototype.s ProtoRemoveAny( param1$, param2$ )
If OpenLibrary( 0, "PB_String_Crunches.dll" )
  RemoveAny.ProtoRemoveAny = GetFunction( 0, "REMOVEANY" )
  s1$ = "Lo38ok2 Ma, n6o nu1mbe78rs!"
  s2$ = "0123456789"
  Debug RemoveAny( s1$, s2$ )
  CloseLibrary(0)
EndIf

I have tried quite a few variations of the PowerBASIC code including exporting a string pointer but whatever I do I get a memory access violation with 'RemoveAny( s1$, s2$ )'

I should add that I am very new to using PureBasic and am probably committing a 'newbie sin'. I have spent sometime searching the forums.

Would someone point out what I am doing wrong?

Thanks

__________________________________________________
Code tags added
03.11.2016
RSBasic
User avatar
Shardik
Addict
Addict
Posts: 2058
Joined: Thu Apr 21, 2005 2:38 pm
Location: Germany

Re: Reading a PowerBASIC dll

Post by Shardik »

PowerBasic and PureBasic are using different string formats. You should take a look into this thread with a similar problem. In the last but one posting of that thread I explain how to use P-BSTR to automatically convert PureBasic strings to PowerBasic strings.

So you instead of calling your PowerBasic DLL with

Code: Select all

Prototype.s ProtoRemoveAny( param1$, param2$ )
you should call it with

Code: Select all

Prototype.s ProtoRemoveAny( param1.p-bstr, param2.p-bstr )
deltarho
New User
New User
Posts: 6
Joined: Fri Jul 06, 2012 5:52 pm

Re: Reading a PowerBASIC dll

Post by deltarho »

Thanks, Shardik - I am with you.

The problem I now have is that the PowerBASIC dll is exporting a string and I cannot use 'Prototype.p-bstr'.

I need to do some more reading - it was good to see off the access violation. :)
deltarho
New User
New User
Posts: 6
Joined: Fri Jul 06, 2012 5:52 pm

Re: Reading a PowerBASIC dll

Post by deltarho »

I have managed it. :D

PowerBASIC code

Code: Select all

#Compile DLL "PB_String_Crunches.dll"
#Dim All
 
Function RemoveAny( ByVal MainString As String, ByVal MatchString As String ) Export As WString
Local sText As WString
 
  sText = Remove$( MainString, Any MatchString )
  Function = sText
 
End Function

PureBasic code

Code: Select all

Prototype.l ProtoRemoveAny( param1.p-bstr, param2.p-bstr )
If OpenLibrary( 0, "PB_String_Crunches.dll" )
  RemoveAny.ProtoRemoveAny = GetFunction( 0, "REMOVEANY" )
  s1$ = "Lo38ok2 Ma, n6o nu1mbe78rs!"
  s2$ = "0123456789"
  MessageRequester("", PeekS(RemoveAny( s1$, s2$ ) ))
  CloseLibrary(0)
EndIf
Resulting in: "Look Ma, no numbers!"
ivega718
User
User
Posts: 15
Joined: Mon Feb 25, 2013 9:29 pm

Re: Reading a PowerBASIC dll

Post by ivega718 »

I was have this problem and I this was answer:

http://www.purebasic.fr/english/viewtop ... t=vegaeval
deltarho
New User
New User
Posts: 6
Joined: Fri Jul 06, 2012 5:52 pm

Re: Reading a PowerBASIC dll

Post by deltarho »

I saw that during my search after Shardik's tip but your link, ivega718, to the PowerBASIC dll is broken so I couldn't see the problem you needed solving.

Shardik's tip solved the PowerBASIC's string parameters and exporting a Wstring solved the problem with exporting a PowerBASIC String. PeekS defaults to reading unicode strings so I was 'home and dry'.
ivega718
User
User
Posts: 15
Joined: Mon Feb 25, 2013 9:29 pm

Re: Reading a PowerBASIC dll

Post by ivega718 »

You can sent me you email to ivega718@hotmail.com and I can sent you the VegaEval.Dll

Israel Vega Alvarez
deltarho
New User
New User
Posts: 6
Joined: Fri Jul 06, 2012 5:52 pm

Re: Reading a PowerBASIC dll

Post by deltarho »

There is no need, Israel, we had the same issue - not realising that PureBasic's default string format clashed with using bstr in PowerBASIC.

Thanks.
deltarho
New User
New User
Posts: 6
Joined: Fri Jul 06, 2012 5:52 pm

Re: Reading a PowerBASIC dll

Post by deltarho »

In practice we probably wouldn't use MessageRequester but something like this

Code: Select all

s3$ = PeekS( RemoveAny( s1$, s2$ )
However, we now have a memory leak.

If we go back to 'Export as String', in the PowerBASIC code then we could do this

Code: Select all

ptr.l = RemoveAny( s1$, s2$ )
s3$ = PeekS( ptr.l, -1, #PB_Ascii )
SysFreeString_( ptr.l )
applePi
Addict
Addict
Posts: 1404
Joined: Sun Jun 25, 2006 7:28 pm

Re: Reading a PowerBASIC dll

Post by applePi »

i have tested the deltarho code above http://purebasic.fr/english/viewtopic.p ... 70#p496402 and it works okay, then i have applied the exact same method to call the powerbasic function Retain$, it has the same structure as Remove$. but here is a strange phenomena:
powerbasic dll:

Code: Select all

#COMPILE DLL "PB_RetainAny.dll"
#DIM ALL

FUNCTION RetainAny( BYVAL MainString AS STRING, BYVAL MatchString AS STRING ) EXPORT AS WSTRING
LOCAL sText AS WSTRING
  'MainString =  "Lo38ok2 Ma, n6o nu1mbe78rs!"
  'MatchString = "0123456789"
   sText = RETAIN$( MainString, ANY MatchString )
  FUNCTION = sText

END FUNCTION 
PureBasic code:

Code: Select all

Prototype.l ProtoRetainAny( param1.p-bstr, param2.p-bstr )
If OpenLibrary( 0, "PB_RetainAny.dll" )
  RetainAny.ProtoRetainAny = GetFunction( 0, "RETAINANY" )
  s1$ = "Lo38ok2 Ma, n6o nu1mbe78rs!"
  s2$ = "20123456789"
  MessageRequester("", PeekS(RetainAny( s1$, s2$ ) ))
  CloseLibrary(0)
EndIf
but the purebasic messageRequester is empty
now uncomment any one line of the 2 lines in the powerbasic dll:

Code: Select all

'MainString =  "Lo38ok2 Ma, n6o nu1mbe78rs!"
'MatchString = "0123456789"
and the purebasic will output the correct result :3826178
i find it strange since the MainString and MatchString does not pass together while they do with the code of deltarho. i miss something ?? . and if possible how to provide these 2 strings by reference to the powerbasic dll
Thanks in advance

EDIT:
the following method works in PB 5.43LTS but uncheck create unicode exec in compiler options

powerbasic DLL:

Code: Select all

#COMPILE DLL "powerbasic_DLL.dll"

FUNCTION MB_Retain ALIAS "Retain" (BYREF param1 AS ASCIIZ * 4096, BYREF param2 AS ASCIIZ * 4096) EXPORT AS STRING
a$=param1
b$=param2
c$ = RETAIN$(a$, ANY b$)
MSGBOX CHR$(34)+c$+CHR$(34)
FUNCTION=c$
END FUNCTION   
purebasic code:

Code: Select all

If OpenLibrary(1,"powerbasic_DLL.dll")

  c.s = "Lo38ok2 Ma, n6o nu1mbe78rs!"
  d.s = "0123456789"
 
  If GetFunction(1,"Retain")
    Debug PeekS(CallFunction(1,"Retain",@c,@d))
  EndIf  
  EndIf

  CloseLibrary(1)
it should output 3826178
williamvanhoecke
User
User
Posts: 65
Joined: Wed Jun 07, 2017 10:13 pm

Re: Reading a PowerBASIC dll

Post by williamvanhoecke »

Shardik's tip solved the PowerBASIC's string parameters and exporting a Wstring solved the problem with exporting a PowerBASIC String. PeekS defaults to reading unicode strings so I was 'home and dry'.
Hello, I am new to PureBasic.
What if you can't change the export to WSTRING (if I do the native powerbasic program that call the dll does not work correctly) ?
I have the same problam as you described but .... I can NOT change the export to WSTRING

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

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)
Post Reply