ProcedureCDLL Return Result
ProcedureCDLL Return Result
I've wrote a DLL Which works quite well within an external program. The problem I'm having is the
return value (Result) from the routine after providing a param. variable to the procedure in the DLL.
See example code below
ProcedureCDLL.i PeekData(D)
Glabal V.i,R.i,V.i
For V=0 To D
R=Array(V)
Next V
Result=R
ProcedureReturn Result
EndProcedure
The above code will crash the program I'm running the DLL from.
Whereas this code works
ProcedureDLL.i PeekSpectrumData_1(100)
Result=Array(100)
ProcedureReturn Result
EndProcedure
I'm sure it's something I'm not doing, any pointers would be helpful.
p.s. My journey with Pure Basic has only just started
Thanks in advance
Leo
return value (Result) from the routine after providing a param. variable to the procedure in the DLL.
See example code below
ProcedureCDLL.i PeekData(D)
Glabal V.i,R.i,V.i
For V=0 To D
R=Array(V)
Next V
Result=R
ProcedureReturn Result
EndProcedure
The above code will crash the program I'm running the DLL from.
Whereas this code works
ProcedureDLL.i PeekSpectrumData_1(100)
Result=Array(100)
ProcedureReturn Result
EndProcedure
I'm sure it's something I'm not doing, any pointers would be helpful.
p.s. My journey with Pure Basic has only just started
Thanks in advance
Leo
Re: ProcedureCDLL Return Result
1 Hi!
2. Please use code tags
3. There is no function Array() in PureBasic.
4. Don't use global within procedures, use Protected. Also "glabal"...
5. We need a runable code for the DLL and the calling program. Even if this means the code crashes.
...
2. Please use code tags
3. There is no function Array() in PureBasic.
4. Don't use global within procedures, use Protected. Also "glabal"...
5. We need a runable code for the DLL and the calling program. Even if this means the code crashes.
...
Good morning, that's a nice tnetennba!
PureBasic 6.21/Windows 11 x64/Ryzen 7900X/32GB RAM/3TB SSD
Synology DS1821+/DX517, 130.9TB+50.8TB+2TB SSD
PureBasic 6.21/Windows 11 x64/Ryzen 7900X/32GB RAM/3TB SSD
Synology DS1821+/DX517, 130.9TB+50.8TB+2TB SSD
Re: ProcedureCDLL Return Result
Welcome!
How can I put this? This code is ... incomplete. We aren't going to be able to help much with incomplete code, but if your actual code looks similar I'm guessing that your crash comes from a stack corruption. Where does "Array()" come from? There are no declarations for it in either sample.
How can I put this? This code is ... incomplete. We aren't going to be able to help much with incomplete code, but if your actual code looks similar I'm guessing that your crash comes from a stack corruption. Where does "Array()" come from? There are no declarations for it in either sample.
Re: ProcedureCDLL Return Result
@jacdelad
Thanks for the reply, sorry about no code tags. The Global works within the routine I use.
Here's the full procedure and yes it's to wrap Fmodex v444.64 inside a DLL to get the array of Singles
for a spectrum. This works, see below.
This is the routine to get individual data elements out of the spectrum array of integers
This will not work and yet if I set the second line of code to
It works
@spikey
Thanks for the reply,
So, how would I protect the stack? An old familiar term in the days of the Z80 etc.
Thanks again
Thanks for the reply, sorry about no code tags. The Global works within the routine I use.
Here's the full procedure and yes it's to wrap Fmodex v444.64 inside a DLL to get the array of Singles
for a spectrum. This works, see below.
Code: Select all
ProcedureDLL GetSpectrumData()
Global Dim SpectrumLeft.f(512) ; Fmod Returns Floats
Global Dim SpectrumRight.f(512); in both channels
Global Dim PeekSpectrum.i(512); Scale Channel floats added to integer
;function FMOD_System_GetSpectrum(system: FMOD_SYSTEM; var spectrumarray: Single; numvalues: Integer; channeloffset: Integer; windowtype: FMOD_DSP_FFT_WINDOW): FMOD_RESULT; stdcall;
; Do the Left channel First
CallFunction(FmodLib,"FMOD_System_GetSpectrum",Fmodsystem,SpectrumLeft(),64,0,0)
; Do the Right channel Second
Result=CallFunction(FmodLib,"FMOD_System_GetSpectrum",Fmodsystem,SpectrumRight(),64,1,0)
; Peek the channel floats then Average to integer Buffer
; All 512 Entries
For Count=0 To 511 Step 1
If IntQ(((SpectrumLeft(Count)+SpectrumRight(Count)))*100)>=100 ; Limit the max value
PeekSpectrum(Count)=50 ; Down
Else
PeekSpectrum(Count)=IntQ(((SpectrumLeft(Count)+SpectrumRight(Count)))*200)+1 ; Everything else Amplify!
EndIf
;SpectrumDatum=Round((SpectrumLeft(Count)+SpectrumRight(Count)/2),#PB_Round_Nearest)
;PeekSpectrum(Count)=Int(SpectrumDatum)
Next Count
ProcedureReturn Result
EndProcedureCode: Select all
ProcedureCDLL.i PeekData(D)
R=PeekSpectrum(V)
Result=R
ProcedureReturn Result
EndProcedure
Code: Select all
R=PeekSpectrum(100) @spikey
Thanks for the reply,
So, how would I protect the stack? An old familiar term in the days of the Z80 etc.
Thanks again
Re: ProcedureCDLL Return Result
Code: Select all
ProcedureCDLL.i PeekData(D)
R=PeekSpectrum(V)
Result=R
ProcedureReturn Result
EndProcedure
Re: ProcedureCDLL Return Result
Sorry Spikey, it should be
V and R are defined at the start of the dll code to be an integer, still the same after the change.
I do intend to look at saving all registers with the inline coder later.
p.s. Back to the days of push and pop!
thanks again
Leo
Code: Select all
ProcedureCDLL.i PeekData(V)
R=PeekSpectrum(V)
Result=R
ProcedureReturn Result
EndProcedureI do intend to look at saving all registers with the inline coder later.
p.s. Back to the days of push and pop!
thanks again
Leo
Re: ProcedureCDLL Return Result
Be mindful of scopes. Global V is not equal to Parameter V:Leo1958 wrote: Mon Sep 23, 2024 6:54 pm V and R are defined at the start of the dll code to be an integer, still the same after the change.
Code: Select all
Global V.i
ProcedureCDLL.i PeekData(V)
Debug "In procedure: " + V
EndProcedure
V = 100
Debug "In main before procedure call: " + V
PeekData(200)
Debug "In main after procedure call: " + VRe: ProcedureCDLL Return Result
Just because it works doesn't mean it's right.
Take a look at the help, it should clear this up:
Global: https://www.purebasic.com/documentation ... lobal.html
Define: https://www.purebasic.com/documentation ... efine.html
Protected: https://www.purebasic.com/documentation ... ected.html
Static: https://www.purebasic.com/documentation ... tatic.html
Threaded: https://www.purebasic.com/documentation ... eaded.html
Global/Define/Threaded for global declaration, Protected/Static for local one.
Then please give use the full code!Leo1958 wrote: Mon Sep 23, 2024 6:54 pm V and R are defined at the start of the dll code to be an integer, still the same after the change.
Good morning, that's a nice tnetennba!
PureBasic 6.21/Windows 11 x64/Ryzen 7900X/32GB RAM/3TB SSD
Synology DS1821+/DX517, 130.9TB+50.8TB+2TB SSD
PureBasic 6.21/Windows 11 x64/Ryzen 7900X/32GB RAM/3TB SSD
Synology DS1821+/DX517, 130.9TB+50.8TB+2TB SSD
Re: ProcedureCDLL Return Result
Morning Jacdelad. Sorry here you go.
please note the PeekSpectrumData_0 routines at the bottom go all the way upto
PeekSpectrum_Data_63, too much to post.
Crude I know, only to see if it worked in getting the Spectrum data
Anyway, Thanks for looking at it, Appreciate it.
Cheers!
please note the PeekSpectrumData_0 routines at the bottom go all the way upto
PeekSpectrum_Data_63, too much to post.
Crude I know, only to see if it worked in getting the Spectrum data
Anyway, Thanks for looking at it, Appreciate it.
Cheers!
Code: Select all
Global FmodSystem.i,Sound.i,Channel.i,file.s,PauseStatus.i,PlayStatus.b,Flag.b,Mode.i
Global Result.i,Count.i
PrototypeC _GetAGKFunction(Function.p-ascii)
ProcedureCDLL ReceiveAGKPtr(*GetFunction)
GetAGKFunction._GetAGKFunction=*GetFunction
EndProcedure
ProcedureDLL Init()
Global FmodLib=OpenLibrary(#PB_Any,"Fmodex64.dll")
ProcedureReturn FmodLib
EndProcedure
ProcedureDLL Play(File)
Result=CallFunction(FmodLib,"FMOD_System_Create",@Fmodsystem)
Result1=CallFunction(FmodLib,"FMOD_System_Init",Fmodsystem,32,0,0) ;FMOD_INIT_NORMAL
Result2=CallFunction(FmodLib,"FMOD_System_CreateStream",Fmodsystem,File,64|2,0,@Sound)
Result3=CallFunction(FmodLib,"FMOD_System_PlaySound",Fmodsystem,0,Sound,0,@Channel)
Global flag=1
ProcedureReturn flag
EndProcedure
ProcedureDLL Stop()
Result=CallFunction(FmodLib,"FMOD_Channel_Stop",Channel)
;Global flag=0
;ProcedureReturn Result
EndProcedure
ProcedureDLL Close()
Result=CallFunction(FmodLib,"FMOD_System_Release",Fmodsystem)
CloseLibrary(FmodLib)
EndProcedure
ProcedureDLL IsPlaying()
CallFunction(FmodLib,"FMOD_Channel_IsPlaying",Channel,@PlayStatus)
If Playstatus=#False
Result=0
Else
Result=1
EndIf
ProcedureReturn Result
EndProcedure
ProcedureDLL Pause()
;Get channel pause status
CallFunction(FmodLib,"FMOD_Channel_GetPaused",Channel, @PauseStatus)
If PauseStatus = #False
CallFunction(FmodLib,"FMOD_Channel_SetPaused",Channel, #True) ;Pause
result=1
Else
CallFunction(FmodLib,"FMOD_Channel_SetPaused",Channel, #False) ;Play
Result=0
EndIf
ProcedureReturn Result
EndProcedure
ProcedureDLL GetSpectrumData()
Global Dim SpectrumLeft.f(512) ; Fmod Returns Floats
Global Dim SpectrumRight.f(512) ; in both channels
Global Dim PeekSpectrum.i(512) ; Scale Channel floats convert to integer
; Do the Left channel First
CallFunction(FmodLib,"FMOD_System_GetSpectrum",Fmodsystem,SpectrumLeft(),511,0,0)
; Do the Right channel Second
Result=CallFunction(FmodLib,"FMOD_System_GetSpectrum",Fmodsystem,SpectrumRight(),511,1,0)
; Peek the channel floats then Average to integer Buffer
; All 512 Entries
For Count=0 To 511 Step 1
If IntQ(((SpectrumLeft(Count)+SpectrumRight(Count)))*100)>=100 ; Limit the max value
PeekSpectrum(Count)=50 ; Down
Else
PeekSpectrum(Count)=IntQ(((SpectrumLeft(Count)+SpectrumRight(Count)))*200)+1 ; Everything else Amplify!
EndIf
Next Count
ProcedureReturn Result
EndProcedure
ProcedureDLL.i PeekSpectrumData()
Result=PeekSpectrum(0)
ProcedureReturn Result
EndProcedure
ProcedureDLL.i PeekSpectrumData_1()
Result=PeekSpectrum(1)
ProcedureReturn Result
EndProcedure
ProcedureDLL.i PeekSpectrumData_2()
Result=PeekSpectrum(2)
ProcedureReturn Result
EndProcedure
ProcedureDLL.i PeekSpectrumData_3()
Result=PeekSpectrum(3)
ProcedureReturn Result
EndProcedure
Re: ProcedureCDLL Return Result
Ok, I must confess I find this code a bit weird. The PeekSpectrumData_x() functions could use a parameter, so you would only need one function instead of 4 (or more).
You absolutely should use EnableExplicit, or I bet you will get problems with your variables later!
Now, show us the complete calling program (or as much code as is needed to get it running). It's hard to understand what happens until your error occurs.
Also: Why use a DLL for the DLL? Is the calling program Non-PB?
You absolutely should use EnableExplicit, or I bet you will get problems with your variables later!
Now, show us the complete calling program (or as much code as is needed to get it running). It's hard to understand what happens until your error occurs.
Also: Why use a DLL for the DLL? Is the calling program Non-PB?
Good morning, that's a nice tnetennba!
PureBasic 6.21/Windows 11 x64/Ryzen 7900X/32GB RAM/3TB SSD
Synology DS1821+/DX517, 130.9TB+50.8TB+2TB SSD
PureBasic 6.21/Windows 11 x64/Ryzen 7900X/32GB RAM/3TB SSD
Synology DS1821+/DX517, 130.9TB+50.8TB+2TB SSD
Re: ProcedureCDLL Return Result
Yes, it’s used in an external program wrote with
AGK Studio. It’s a plugin to that program and yes
The routine would far easier to pass a variable to it inside
A loop.
Out at the moment will look at you suggestion later
When home.
Cheers
Leo
Ps Oscilloscope data working with similar multiple
Routines to get the wave shape.
AGK Studio. It’s a plugin to that program and yes
The routine would far easier to pass a variable to it inside
A loop.
Out at the moment will look at you suggestion later
When home.
Cheers
Leo
Ps Oscilloscope data working with similar multiple
Routines to get the wave shape.


