title: Calling C code from within Ruby -- How to use the returned pointer?
body: <p><strong>Problem:</strong></p>
  
  <p>I'd like to use in my Ruby program an algorithm that is coded in C and exposed through a DLL.</p>
  
  <p>I would like to treat the algorithm as a black box that I can call from within Ruby -- simply pass in the required parameters and use the result.</p>
  
  <p>Ruby (both 1.8.7 and 1.9.3) has the <code>Win32API</code> module which seems intended to make it quite easy to interface with dynamic libraries to do exactly what I'm after.</p>
  
  <p>But the problem is that I can't seem to get the Win32API call to send back a string.</p>
  
  <p><strong>Details:</strong></p>
  
  <p>The third-party C function is <code>CodeGen()</code>.  It take 6 parameters, including a source string, an arbitrary string to serve as encryption key, and, for simplicity, 4 numerical parameters, one signed int, one unsigned long, and two unsigned shorts.  From these, CodeGen() implements a black-box algorithm to return a resulting string.</p>
  
  <p>The C prototype for CodeGen() is:</p>
  
  <pre><code>const char *CodeGen(  int encryp_level, 
                       const char *source_str, const char *encryp_key,
                       unsigned long param_a, 
                       unsigned short param_b, unsigned short param_c
                    )
  </code></pre>
  
  <p>Note that both the input strings are constants, i.e. they are supplied to CodeGen() as strings -- so pointers to constant strings</p>
  
  <p>The return value for CodeGen() is also a string, of fixed maximum length, so it will return a pointer.</p>
  
  <p><strong>My Question:</strong></p>
  
  <p>How do I go about setting up the call to CodeGen() and getting back the string it is supposed to generate?</p>
  
  <p><strong>My attempts:</strong></p>
  
  <p>The code below simply gives me integers as the return value, when I am expecting to obtain a string.</p>
  
  <pre><code>require 'Win32API'
  
  codeGen = Win32API.new("encrypt.dll", "CodeGen", "ISSIII", "S")
  
  ret_str = codeGen.Call(3, "foo", "bar", 0, 0, 0)
  
  puts ret_str
  </code></pre>
  
  <p>However, instead of getting a string back, I get back an integer.  <strong>Edit: Could this be a pointer?</strong></p>
  
  <p>Although I'm using Ruby 1.9.3 on Windows 7, 64-bit edition, I've also tested the above on Windows XP, 32-bits, and using Ruby 1.8.7, so I'm pretty sure it's something to do with my use of the Win32API itself.</p>
  
  <p>Not sure whether the problem is any of these:</p>
  
  <ul>
  <li>do the integers (3, 0, ...) need to be packed? </li>
  <li>do I need to distinguish between short and long types? </li>
  <li>am I not properly handling the return value?</li>
  <li>if the return value is a pointer, how do I use this in Ruby?</li>
  <li>something else?</li>
  </ul>
  
  <p>Any insight would be much appreciated!</p>