title: Nim: How to pass an array of varying size to an argument of a foreign function calling into a .dll?
body: <p>Bellow is a minimal example when wrapping the OpenAL32.dll.  The foreign function <code>alcCreateContext</code> has the argument <code>attrlist</code> which takes a <code>ptr</code> to an array of type <code>ALCint</code> or <code>nil</code>.  The issue is the array can be of different lengths depending on the amount of different flags passed in.  The array should be organized as [flag, int, flag, int, ...].  How can this be accomplished in a more dynamic way allowing the inclusion of <code>ALC_FREQUENCY</code> for example? The array size is currently hard coded into the procedure and its nasty.</p>
  <pre><code>when defined(windows):
    {.push cdecl, dynlib: &quot;OpenAL32.dll&quot;, importc.}
  else:
    {.push importc.}
  
  type 
    ALCint = cint
    ALCdevice* = pointer
    ALCcontext* = pointer
  
  const
    ALC_MONO_SOURCES* = 0x00001010
    ALC_STEREO_SOURCES* = 0x00001011
    ALC_FREQUENCY* = 0x00001007
  
  proc alcCreateContext*(device: ALCdevice; attrlist: ptr array[0..3, ALCint]): ALCcontext
  proc alcOpenDevice*(devicename: cstring): ALCdevice
  
  const attributes = [ALC_MONO_SOURCES.ALCint, 65536.ALCint, ALC_STEREO_SOURCES.ALCint, 65536.ALCint]
  
  discard alcOpenDevice(nil).alcCreateContext(attributes.unsafeAddr)
  
  </code></pre>
  <p>I experimented with <code>openArray</code> and other containers.  Is the solution some sort of <code>cast</code>?  This is also the workaround for getting more then 256 sounds out of OpenAL.</p>
  <h2>Answer from PMunch.  Thank You.</h2>
  <p>The foreign function now wants <code>ptr UncheckedArray[ALCint]</code> and when passing the argument use <code>cast[ptr UncheckedArray[ALCint]](attributes.unsafeAddr)</code></p>
  <pre><code>when defined(windows):
    {.push cdecl, dynlib: &quot;OpenAL32.dll&quot;, importc.}
  else:
    {.push importc.}
  
  type 
    ALCint = cint
    ALCdevice* = pointer
    ALCcontext* = pointer
  
  const
    ALC_MONO_SOURCES* = 0x00001010
    ALC_STEREO_SOURCES* = 0x00001011
    ALC_FREQUENCY* = 0x00001007
  
  proc alcCreateContext*(device: ALCdevice; attrlist: ptr UncheckedArray[ALCint]): ALCcontext
  proc alcOpenDevice*(devicename: cstring): ALCdevice
  
  const attributes = [ALC_MONO_SOURCES.ALCint, 65536.ALCint, ALC_STEREO_SOURCES.ALCint, 65536.ALCint]
  
  discard alcOpenDevice(nil).alcCreateContext(cast[ptr UncheckedArray[ALCint]](attributes.unsafeAddr))
  
  </code></pre>