Prototypes, strings and DLL again

Just starting out? Need help? Post your questions and find answers here.
User avatar
luis
Addict
Addict
Posts: 3895
Joined: Wed Aug 31, 2005 11:09 pm
Location: Italy

Prototypes, strings and DLL again

Post by luis »

Does this qualify as a bug ?

CLIENT

Code: Select all

EnableExplicit

#PROTO_WITH_STRING = 1

Define a$

CompilerIf #PROTO_WITH_STRING = 1

If OpenLibrary(0, "lib.dll")       
    Prototype.s p_Proc1 (a$, b$) ; this will not work
    Global Proc1.p_Proc1 = GetFunction(0, "Proc1")
EndIf

a$ = Proc1 ("hello", "fred") ; no way

CompilerElse

If OpenLibrary(0, "lib.dll")       
    Prototype.i p_Proc1 (a$, b$) ; this will work using PeekS
    Global Proc1.p_Proc1 = GetFunction(0, "Proc1")
EndIf

a$ = PeekS(Proc1 ("hello", "fred")) ; why can't the compiler do this looking at the Prototype ?

CompilerEndIf

Debug "a$ = " + a$


DLL (lib.dll)

Code: Select all

 Global Ret$

ProcedureDLL.s Proc1 (a$, b$)
 Ret$ = a$ + " " + b$   
 ProcedureReturn Ret$
EndProcedure

See also (similar but using Imports) -> http://www.purebasic.fr/english/viewtop ... =3&t=40926

And this (DLL limitations and good practice to follow ?) -> http://www.purebasic.fr/english/viewtop ... 13&t=42537
"Have you tried turning it off and on again ?"
A little PureBasic review
GBeebe
Enthusiast
Enthusiast
Posts: 263
Joined: Sat Oct 09, 2004 6:52 pm
Location: Franklin, PA - USA
Contact:

Re: Prototypes, strings and DLL again

Post by GBeebe »

Agreed, but I thought it was standard for the pointer to a string to be returned by a DLL instead of the whole string itself. It's common in all DLLs that return "strings" and languages, right?

[Edit]
Because of something like this:

Code: Select all

*Name = GetUserName(something)
If *Name = #NUL
  ;something went wrong
ElseIf PeekS(*Name) = ""
  ;the user didn't supply a name.
  UserName.s = "Anonymous"
Else
  UserName.s = PeekS(*Name)
EndIf
User avatar
blueznl
PureBasic Expert
PureBasic Expert
Posts: 6166
Joined: Sat May 17, 2003 11:31 am
Contact:

Re: Prototypes, strings and DLL again

Post by blueznl »

GBeebe wrote:Agreed, but I thought it was standard for the pointer to a string to be returned by a DLL instead of the whole string itself. It's common in all DLLs that return "strings" and languages, right?
Either return a pointer, or (perhaps even better) allocate some memory, then call the DLL function with a pointer to that memory. Many DLL's return the required size of the buffer if they are passed a 0 as buffer address.
( PB6.00 LTS Win11 x64 Asrock AB350 Pro4 Ryzen 5 3600 32GB GTX1060 6GB)
( The path to enlightenment and the PureBasic Survival Guide right here... )
User avatar
luis
Addict
Addict
Posts: 3895
Joined: Wed Aug 31, 2005 11:09 pm
Location: Italy

Re: Prototypes, strings and DLL again

Post by luis »

GBeebe wrote:Agreed, but I thought it was standard for the pointer to a string to be returned by a DLL instead of the whole string itself. It's common in all DLLs that return "strings" and languages, right?


Yes, but read below...
blueznl wrote: Either return a pointer, or (perhaps even better) allocate some memory, then call the DLL function with a pointer to that memory. Many DLL's return the required size of the buffer if they are passed a 0 as buffer address.
Yes, it's a common way to communicate used in many APIs and I've considered that.

But my points are:

1) I have specified using prototypes the return type is a string. And if I assign the returned value through PeekS() to a string all works well. So why the compiler don't do that by itself ? It just knows. This is the first question.

1a) Is this a bug (I would call it a bug or a level of unexpected missing functionality if you like!) ? Second question.

2) Since it seem the compiler could do that, why force me to write DIFFERENT code in the client depending on my calling a proc from dll or from the source code directly, for example ? This is a little annoying because I would like to be able to release something in DLL form initially, and maybe later in source form, and the user (programmer) could use the same client code without modifications.

I know I could probably ALWAYS return the address of the string (using DLL or included source), but if it can be avoided and uniformed to the usual way of returning strings it would be better...

Unless there is a reason behind for all this (but again see point 1).

Comments ? Suggestions ?
"Have you tried turning it off and on again ?"
A little PureBasic review
Foz
Addict
Addict
Posts: 1359
Joined: Tue Nov 13, 2007 12:42 pm
Location: Manchester, UK

Re: Prototypes, strings and DLL again

Post by Foz »

Just to raise this an issue again, but why doesn't Prototype.s work the same as Prototype.i + PeekS()?
User avatar
Danilo
Addict
Addict
Posts: 3036
Joined: Sat Apr 26, 2003 8:26 am
Location: Planet Earth

Re: Prototypes, strings and DLL again

Post by Danilo »

Returning .s works only PB-Internal, together with PB's internal string-buffer.
The external DLL/lib does not write to PB's internal string buffer.

Code: Select all

Prototype.s p_Proc1 (a$, b$)

Procedure.s test_proc(a$,b$)
    ProcedureReturn a$+b$
EndProcedure

Define f.p_Proc1 = @test_proc()

x$ = f("Hello"," World!")
Debug x$
Of course it would be better if Prototype.s, Prototype.p-ascii, Prototype.p-utf8, and Prototype.p-unicode
would just work and do automatically PeekS(), except for 0-pointers.
PeekS(0,-1,#PB_Ascii) does currently not check for 0-pointers. In my opinion such functions should check
for 0-pointers and return an empty string, instead crashing. I mean in the final exe, without debugger.
User avatar
kenmo
Addict
Addict
Posts: 2033
Joined: Tue Dec 23, 2003 3:54 am

Re: Prototypes, strings and DLL again

Post by kenmo »

Danilo wrote:Of course it would be better if Prototype.s, Prototype.p-ascii, Prototype.p-utf8, and Prototype.p-unicode
would just work and do automatically PeekS(), except for 0-pointers.
I agree with this! Time for a Feature Request?

In fact a Prototype with return type .s seems "dangerous" because PureBasic doesn't know what string format the DLL uses! Since you are defining the prototype and you know its input formats, you should know (and be able to specify) its output format too.

(That's why returning a pointer, and using PeekS() with the appropriate format, is currently the best method.)
Post Reply