Export PB functions in DLL with array input

Just starting out? Need help? Post your questions and find answers here.
copperd
New User
New User
Posts: 9
Joined: Thu Jul 21, 2016 1:43 pm

Export PB functions in DLL with array input

Post by copperd »

I am playing around with writing some functions in PB and using them in LabVIEW. I keep crashing when accessing the functions that have have arrays in the prototype.

My guess is that arrays are not handled just as pointers in PB.

Code: Select all

ProcedureDLL Maskfunction(Array Image.u(1), Array mask.a(1), Array Result.i(1),count.i)
  
  For x = 0 To count.i
    If mask.a(x) & 1 > 0
      Result.i(0) = Result.i(0) + Image.u(x)
    EndIf
    If mask.a(x) & 2 > 0
      Result.i(1) = Result.i(1) + Image.u(x)
    EndIf
    If mask.a(x) & 4 > 0
      Result.i(2) = Result.i(2) + Image.u(x)
    EndIf
    If mask.a(x) & 8 > 0
      Result.i(3) = Result.i(3) + Image.u(x)
    EndIf
    If mask.a(x) & 16 > 0
      Result.i(4) = Result.i(4) + Image.u(x)
    EndIf
    If mask.a(x) & 32 > 0
      Result.i(5) = Result.i(5) + Image.u(x)
    EndIf
    Result.i(6) = Result.i(6) + Image.u(x)
  Next
  
  
  
EndProcedure
I get the following warnings but not much to go on in terms of documentation.

[08:31:03] [COMPILER] Line 1: Warning: List, Array and Map parameters can cause issue when exported with ProcedureDLL.
[08:31:03] [COMPILER] Line 1: Warning: List, Array and Map parameters can cause issue when exported with ProcedureDLL.
[08:31:03] [COMPILER] Line 1: Warning: List, Array and Map parameters can cause issue when exported with ProcedureDLL.
[08:31:03] Compilation succeeded with 3 warning(s).

I seen the DLLsample.pb and the part about "The declaration of arrays, lists or map with Dim, NewList or NewMap must always be done inside the procedure AttachProcess." I feel I am missing some key part of information.


I seen some code here http://forums.purebasic.com/english/vie ... p?p=201276 for accessing a point as an array. Would the correct procedure be to bring in the pointer and use a structure with an array element of correct bit size set to the size?

Hmmm this works just fine. I am toying around as I write this.

Code: Select all

ProcedureDLL.i SumArray(*Array_ptr ,count.i)
  sum.i
 Structure MemoryArray
  StructureUnion
    Byte.b[0]
  EndStructureUnion
EndStructure
*Array.MemoryArray = *Array_ptr

For x = 0 To count - 1
  sum = sum + *Array\Byte[x]
Next

ProcedureReturn sum

EndProcedure
Is this the correct way to do this or a hack?
User avatar
skywalk
Addict
Addict
Posts: 4235
Joined: Wed Dec 23, 2009 10:14 pm
Location: Boston, MA

Re: Export PB functions in DLL with array input

Post by skywalk »

Yes, pass pointers to your arrays.
Use '*myArray.Integer' instead of 'Array myArray.x(1)'.
Then assign the pointer before ProcedureReturn:
*myArray\i = @myArray()
The nice thing about standards is there are so many to choose from. ~ Andrew Tanenbaum
copperd
New User
New User
Posts: 9
Joined: Thu Jul 21, 2016 1:43 pm

Re: Export PB functions in DLL with array input

Post by copperd »

Skywalk thank you for the quick reply.

This is the code I already came up with that works.

Code: Select all

ProcedureDLL Maskfunction(*Imageprt, *Maskprt, *Resultprt, count.i)
  Structure MemoryArray
    StructureUnion
      u8.a[0]
      u16.u[0]
      i64.q[0]
    EndStructureUnion
  EndStructure
  *Image.MemoryArray = *Imageprt
  *Mask.MemoryArray = *Maskprt
  *Result.MemoryArray = *Resultprt
  
  

  
  
  For x = 0 To count - 1
    If *Mask\u8[x] & 1 > 0
      *Result\i64[0] = *Result\i64[0] + *Image\u16[x]
    EndIf
    If *Mask\u8[x] & 2 > 0
      *Result\i64[1] = *Result\i64[1] + *Image\u16[x]
    EndIf
    If *Mask\u8[x] & 4 > 0
      *Result\i64[2] = *Result\i64[2] + *Image\u16[x]
    EndIf
    If *Mask\u8[x] & 8 > 0
      *Result\i64[3] = *Result\i64[3] + *Image\u16[x]
    EndIf
    If *Mask\u8[x] & 16 > 0
      *Result\i64[4] = *Result\i64[4] + *Image\u16[x]
    EndIf
    If *Mask\u8[x] & 32 > 0
      *Result\i64[5] = *Result\i64[5] + *Image\u16[x]
    EndIf
    *Result\i64[6] = *Result\i64[6] + *Image\u16[x]
  Next
  
  
  
EndProcedure
It looks like your suggesting something that might make this alittle more readable.
User avatar
skywalk
Addict
Addict
Posts: 4235
Joined: Wed Dec 23, 2009 10:14 pm
Location: Boston, MA

Re: Export PB functions in DLL with array input

Post by skywalk »

Well, you are using a complicated construct and without bounds checks?
A more direct method would be to create global arrays in your dll with an init() procedure.
Then you can Dim/ReDim them with whatever sizing you require and reference them with the pointers I mentioned. Remember to free the arrays on dll detachprocess().
The nice thing about standards is there are so many to choose from. ~ Andrew Tanenbaum
User avatar
Lunasole
Addict
Addict
Posts: 1091
Joined: Mon Oct 26, 2015 2:55 am
Location: UA
Contact:

Re: Export PB functions in DLL with array input

Post by Lunasole »

skywalk wrote: Remember to free the arrays on dll detachprocess().
Is that really necessary? I didn't ever encountered any visible problems (including ones visible in process statistics - used memory, etc) while not releasing any global array or map on DLL unload


UPD: Also just added 500mb global array to one of my dlls for testing. I didn't released it in detachprocess, but anyway that used memory was properly released on DLL unload (while host-process continued to work). Bad that PB docs lack of information about this, they just saying "no, you can't" and doesn't answer why.
"W̷i̷s̷h̷i̷n̷g o̷n a s̷t̷a̷r"
User avatar
skywalk
Addict
Addict
Posts: 4235
Joined: Wed Dec 23, 2009 10:14 pm
Location: Boston, MA

Re: Export PB functions in DLL with array input

Post by skywalk »

I prefer to explicitly manage whatever memory I create. It is just habit and while modern o/s may perform these duties, it is not so much code. I've read somewhere that the o/s may retain dll memory in anticipation of repeated use. And this becomes complicated when/if the calling process crashes or hangs.
The nice thing about standards is there are so many to choose from. ~ Andrew Tanenbaum
User avatar
Lunasole
Addict
Addict
Posts: 1091
Joined: Mon Oct 26, 2015 2:55 am
Location: UA
Contact:

Re: Export PB functions in DLL with array input

Post by Lunasole »

Well it all depends on HeapCreate/HeapDestroy API (on windows).
I guessed PB does FreeArray() for every array allocated on program end, but it not happens, just HeapDestroy is called as seen from dll assembly.
But it looks like all PB stuff like arrays are based on that allocated heap, so cleaned up properly without freeing them separately.

But generally you're right, it is always better to ensure. I'm just often too lazy to do such doubtful actions ^^ (as it can be time waste)
"W̷i̷s̷h̷i̷n̷g o̷n a s̷t̷a̷r"
Post Reply