# How to pack/unpack nested structures?

**URL:** <https://www.ruby-forum.com/t/how-to-pack-unpack-nested-structures/98123>\
**Category:** Ruby\
**Created:** [July 12, 2006, 5:34pm UTC](https://www.ruby-forum.com/t/how-to-pack-unpack-nested-structures/98123 "2006-07-12T17:34:31Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![vtphysguy](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/v/77aa72/32.png) [@vtphysguy](https://www.ruby-forum.com/u/vtphysguy)\
**Post date:** [July 12, 2006, 5:34pm UTC](https://www.ruby-forum.com/t/how-to-pack-unpack-nested-structures/98123/1 "2006-07-12T17:34:31Z")

</div>

I am accessing the Win32 API from Ruby, and am having trouble dealing  
with  
structures that nest structures. How should I pack/unpack these objects?  
Ruby/DL looks like it would give me a hand but I’m not sure how to use  
it.

Here is an example of what I’m doing. I’m calling a function,  
InitializeSecurityContext, which as one of its arguments takes a pointer  
to  
a SecBufferDesc structure. This structure contains a pointer to a  
SecBuffer  
structure. The structures look mostly like this:

struct SecBufferDesc {  
long version;  
long numBuffers;  
SecurityBuffer \* buffers;  
}

struct SecurityBuffer {  
long bufferSize;  
long bufferType;  
void \* buffer;  
}

I am unclear on how to pack a string to contain such a structure. This  
sort  
of works, but I am unable to access the inner structure:

version = 1  
numBuffers = 1

bufferSize = 100  
bufferType = 2  
buffer = “\0” \* bufferSize

struct = [version, numBuffers, [bufferSize, bufferType,  
buffer].pack(“LLP”)].pack(“LLP”)

After calling the method with ‘struct’, I can unpack the outer structure

struct.unpack(“LLP12”) # gives SecBufferDesc structure

But when I try to access the inner SecBuffer structure, I get an errror:

secBuffPtr = struct.unpack(“LLP12”)[2]  
secBuffPtr.unpack(“LLP12”) # gives ‘no associated pointer’ error

What’s interesting is the packing process seems to work, because the  
function called correctly writes to the structures in memory. However, I  
cannot then unpack the string to get access to the structures!

How can I pack the structure correctly to get to the inner structure?  
Thanks  
for any help in advance!

Justin

p.s. Here is a short file that demonstrates the problem, without any  
need  
for API calls:

version = 1  
count = 1

size = 100  
type = 2  
buffer = “\0” \* size

struct = [version, count, [size, type, buffer].pack(“LLP”)].pack(“LLP”)

outerStruct = struct.unpack(“LLP12”)  
puts “structure is: #{outerStruct.inspect}”

begin  
innerStruct = outerStruct[2].unpack(“LLP12”)  
puts “innerStruct is #{innerStruct.inspect}”  
rescue ArgumentError  
puts “unable to unpack inner structure”  
end

---

<div class="post-metadata">

**Author:** ![vtphysguy](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/v/77aa72/32.png) [@vtphysguy](https://www.ruby-forum.com/u/vtphysguy)\
**Post date:** [July 14, 2006, 5:19pm UTC](https://www.ruby-forum.com/t/how-to-pack-unpack-nested-structures/98123/2 "2006-07-14T17:19:33Z")

</div>

Hi,

At Thu, 13 Jul 2006 00:31:37 +0900,  
Justin B. wrote in [ruby-talk:201532]:

> version = 1  
> numBuffers = 1
> 
> bufferSize = 100  
> bufferType = 2  
> buffer = “\0” \* bufferSize

I guess this buffer is the answer, unless the function returns  
another pointer.

> struct = [version, numBuffers, [bufferSize, bufferType,  
> buffer].pack(“LLP”)].pack(“LLP”)

or:

nested\_struct = [bufferSize, bufferType, buffer].pack(“LLP”)  
struct = [version, numBuffers, inner\_struct].pack(“LLP”)

nested\_struct.unpack(“LLP12”)

If the function alters buffer of struct SecurityBuffer, says it  
allocates new buffer and returns it, unpack can’t deal with it.  
You need DL instead.

---

<div class="post-metadata">

**Author:** ![vtphysguy](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/v/77aa72/32.png) [@vtphysguy](https://www.ruby-forum.com/u/vtphysguy)\
**Post date:** [July 14, 2006, 6:00pm UTC](https://www.ruby-forum.com/t/how-to-pack-unpack-nested-structures/98123/3 "2006-07-14T18:00:54Z")

</div>

On 7/14/06, removed\_email\_address@domain.invalid [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> nested\_struct = [bufferSize, bufferType, buffer].pack(“LLP”)  
> struct = [version, numBuffers, inner\_struct].pack(“LLP”)
> 
> nested\_struct.unpack(“LLP12”)
> 
> If the function alters buffer of struct SecurityBuffer, says it  
> allocates new buffer and returns it, unpack can’t deal with it.  
> You need DL instead.

Would you mind demonstrating how I can use DL to do it? I’d love to use  
that  
library but I wasn’t able to figure it out … Thanks for your time and  
attention!

Justin
