Page 1 of 1

DLL returning an integer

Posted: Tue Apr 09, 2024 1:51 pm
by charvista
Hello again,
I am studying the DLL concept and I am doing some try-and-error's.
Returning a value with String, it works fine.
But apparently not with integers.... (see MyFourthFunction())
Is string the only way to return something from a DLL function call ?

Code: Select all

; My first DLL's => to be saved as "PureBasic.dll"
ProcedureDLL MyFirstFunction()
    MessageRequester("Hello","This is a PureBasic DLL !",0)
EndProcedure
ProcedureDLL MySecondFunction()
    MessageRequester("Hello","This is my second function, working fine together",0)
EndProcedure
ProcedureDLL.s MyThirdFunction()
    ProcedureReturn "returned-some-string"
EndProcedure
ProcedureDLL.i MyFourthFunction()
    ProcedureReturn 103
EndProcedure

Code: Select all

EnableExplicit
Define.s string
Define.i integ

If OpenLibrary(0, "PureBasic.dll")
    CallFunction(0, "MyFunction")
    CallFunction(0, "MySecondFunction")
    string.s=PeekS(CallFunction(0,"MyThirdFunction"))
    MessageRequester("Returned value:",string)
    integ.i=PeekI(CallFunction(0,"MyFourthFunction"))
    MessageRequester("Returned value:",Str(integ))
    CloseLibrary(0)
EndIf

Re: DLL returning an integer

Posted: Tue Apr 09, 2024 2:09 pm
by infratec
Read the help for CallFunction()

Code: Select all

integ.i=CallFunction(0,"MyFourthFunction")
But you should use Import or Prototypes and not CallFunction.

Re: DLL returning an integer

Posted: Tue Apr 09, 2024 3:32 pm
by charvista
Ok, no PeekI() needed, thanks.
Ok, use of Import or Prototypes are recommended instead of CallFunction.
So, Prototypes handles .dll files so I think it is the same way to create the .dll (with Compiler set to Executable Format: Shared DLL)
But Import handles .lib files instead of .dll. How do we create a .lib file? By writing the name of the lib in the field "Library Subsystem:"?

Re: DLL returning an integer

Posted: Tue Apr 09, 2024 3:56 pm
by AZJIO
It happened

Code: Select all

EnableExplicit

; It's like the contents of structures
Prototype.i MyThirdFunction(string.p-unicode)
Prototype.i MyFourthFunction(*i.Integer)

Define String$
Define num
; It's like declaring structures
Define My3Function.MyThirdFunction
Define My4Function.MyFourthFunction

If OpenLibrary(0, "PureBasic.dll")
	My3Function = GetFunction(0, "MyThirdFunction") ; gets a pointer to a function
	My4Function = GetFunction(0, "MyFourthFunction")
	
	Debug My4Function(@num) ; Call
	MessageRequester("", Str(num))
	
	String$ = Space(256)
	Debug My3Function(String$) ; a pointer to a string of size 256 is passed
	MessageRequester("", String$)
	
	CloseLibrary(0)
EndIf
DLL

Code: Select all

ProcedureDLL MyThirdFunction(*s.String)
	PokeS(*s, "returned-some-string")
    ProcedureReturn 32
EndProcedure

ProcedureDLL MyFourthFunction(*i.Integer)
; 	PokeI(@*i\i, 104)
; 	PokeI(*i, 104)
	*i\i = 104
    ProcedureReturn 103
EndProcedure

Re: DLL returning an integer

Posted: Tue Apr 09, 2024 4:28 pm
by charvista
Nice example, thank you AZJIO. :wink: Through your code, I have seen that Debug and MessageRequester give different return values, so the string is returned ByRef.
For now, a real "Chinese puzzle", but I understand perfectly what is happening.
I only need to get accustomed.... :mrgreen:

Edit: I saw your edit - better example, also showing how to return 103/104. Super!

Re: DLL returning an integer

Posted: Wed Apr 10, 2024 8:52 am
by AZJIO
Building a DLL
When using CallFunction() (or one of its similar CallXXX functions) on a DLL function you will get a pointer on the return string, which you could read with PeekS().
Using a pointer to the structure *s.String is not relevant, replace it with a pointer *s. I did some tests and I couldn't use *s\s.

In the reference file in the DLL description, it is useful to make a reference to Prototype, and in the Prototype description make a reference to "Building a DLL".

Re: DLL returning an integer

Posted: Wed Apr 10, 2024 9:48 am
by mk-soft
Normally you pass the buffer size for the string

Code: Select all

ProcedureDLL MyThirdFunction(*sResult, cntChar)
  Protected r1.s, len
  r1 = "returned-some-string"
  len = Len(r1)
  If *sResult
    If len > cntChar
      len = cntChar
    EndIf
    PokeS(*sResult, "returned-some-string", len)
  EndIf
  ProcedureReturn len
EndProcedure

; Main

cnt = MyThirdFunction(0, 0)
Debug cnt
Result.s = Space(cnt)
cnt = MyThirdFunction(@Result,  cnt)
Debug Result

Re: DLL returning an integer

Posted: Wed Apr 10, 2024 6:02 pm
by charvista
Thanks mk-soft for the trick.

Question for having the confirmation:
If a ProcedureDLL is used in the local program (thus not as an extern DLL file), is it working 100% like a standard Procedure?

Code: Select all

ProcedureDLL.s Software()
    ProcedureReturn "PBM-Software"
EndProcedure
v1.s=Software()
Debug v1

Re: DLL returning an integer

Posted: Wed Apr 10, 2024 10:42 pm
by mk-soft
Yes