On Fri, Dec 26, 2008 at 9:54 AM, Ben Simon <span dir="ltr">&lt;<a href="mailto:benjisimon@gmail.com">benjisimon@gmail.com</a>&gt;</span> wrote:<br><div class="gmail_quote"><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
<div class="Ih2E3d">On Fri, Dec 26, 2008 at 7:16 AM, troels knak-nielsen <span dir="ltr">&lt;<a href="mailto:troelskn@gmail.com" target="_blank">troelskn@gmail.com</a>&gt;</span> wrote:<br></div><div class="gmail_quote"><div class="Ih2E3d">
<blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
I had a similar problem a few months back. Have a look over here:<br>
<a href="http://stackoverflow.com/questions/105816/how-do-i-access-a-char-through-ffi-in-plt-scheme" target="_blank">http://stackoverflow.com/questions/105816/how-do-i-access-a-char-through-ffi-in-plt-scheme</a></blockquote>

</div><div><br>Figures, the exact question I was asking was already asked - typical.<br><br>The answer doesn&#39;t really make sense to me. But, it gives me a place to start, and I&#39;ll mull it over from there.</div></div>
</blockquote><div><br>I&#39;ve mulled it over, and gotten closer, but am not quite there yet.<br><br>The return type of mysql-fetch-row is described as:<br><br><div style="margin-left: 40px;">This is a type-safe representation of one row of data. It is currently 
implemented as an array of counted byte strings.&nbsp; <br><br></div>If I ignore for a second that they are byte counted strings, and not strings represented by a final null, I can write:<br><br><div style="margin-left: 40px;">
(defmysql mysql-fetch-row : _result -&gt; (_vector o _string (mysql-field-count)))<br></div><br>(see below for all the source code.&nbsp; Though, everything after the : above is re-written into a (_fun ...))<br><br>This works remarkably well, but mysql-fetch-row returns NULL to signify the end of result set has been reached.<br>
<br>With the above, I get the following error message when the end of a result set is hit:<br><br>&nbsp;&nbsp; ptr-ref: expects type &lt;non-null-cpointer&gt; as 1st argument, given: #f; other arguments were: #&lt;ctype&gt; 1<br><br>
Any suggestions for how to handle this?<br><br>I feel like I want to somehow use _cpointer/null - but just wrapping the above in a _cpointer/null doesn&#39;t appear to help.<br><br>Also, to make this really robust, I&#39;m going to need to think of this as a vector of _pointer&#39;s and then make byte strings out of them using the lenghts mysql tells me about.&nbsp; Part of this solution seems straightforward:<br>
<br>&nbsp;;; careful, psudo code below<br>&nbsp;(define _row (make-ctype (_vector o _pointer (mysql-field-count)) #f<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (lambda (row)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ;; row is a vector of _pointer&#39;s into strings<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (for/list ([ptr row]<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [length (mysql-fetch-lengths RESULT)])<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (<span class="schemeparen"></span><a name="(dep._((lib._scribblings/foreign/unsafe-foreign..ss)._make-sized-byte-string))"></a><a name="(def._((lib._scribblings/foreign/unsafe-foreign..ss)._make-sized-byte-string))"></a><span title="Provided from: scribblings/foreign/unsafe-foreign"><span class="schemesymbol"><a href="file:///C:/Program%20Files/PLT/doc/foreign/foreign_pointer-funcs.html#%28def._%28%28lib._scribblings/foreign/unsafe-foreign..ss%29._make-sized-byte-string%29%29" class="schemevaluelink">make-sized-byte-string</a></span></span><span class="hspace"> </span><span class="schemevariable">ptr </span><span class="hspace"></span><span class="schemevariable">length</span><span class="schemeparen">)</span><span class="hspace">))))<br>
<br><br>The tricky part here is that I need access to RESULT - which is the value passed into mysql-fetch-row.&nbsp; Any suggestions for how I can arrange for this argument to be available for the ctype of resulting row?<br><br>
Thanks again for all help.&nbsp; Hopefully, this knowledge will be useful to others who come along and want to develop their own FFIs.<br><br>-Ben<br><br>(require scheme/foreign)<br>(unsafe!)<br><br>(define current-mysql-handle (make-parameter #f))<br>
<br>(define libmysql (ffi-lib &quot;libmysql&quot;))<br><br>(define _handle (make-ctype _pointer #f <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (lambda (handle)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (when handle (register-finalizer handle mysql-close))<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; handle)))<br><br>(define _result (make-ctype _pointer #f<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (lambda (results)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (when results (register-finalizer results mysql-free-result))<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; results)))<br><br>(define _data (make-ctype _pointer #f<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (lambda (data)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (if data<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; data<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (error &#39;mysql (mysql-error))))))<br>
<br>(define _ok? (make-ctype _int #f<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (lambda (val)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (if (= val 0) #t<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (error &#39;mysql (mysql-error))))))<br><br>(define-fun-syntax _handle*<br>
&nbsp; (syntax-id-rules ()<br>&nbsp;&nbsp;&nbsp; [_ (type: _handle expr: (current-mysql-handle))]))<br><br>(define-fun-syntax _null_ptr*<br>&nbsp; (syntax-id-rules ()<br>&nbsp;&nbsp;&nbsp; [_ (type: _pointer expr: #f)]))<br><br>(define-syntax defmysql <br>&nbsp; (syntax-rules (:)<br>
&nbsp;&nbsp;&nbsp; [(_ name : type ...)<br>&nbsp;&nbsp;&nbsp;&nbsp; (define name (get-ffi-obj (regexp-replaces &#39;name &#39;((#rx&quot;-&quot; &quot;_&quot;) (#rx&quot;[*?]$&quot; &quot;&quot;)))<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; libmysql (_fun type ...)))]))<br>
<br>(defmysql mysql-init : _null_ptr* -&gt; _handle)<br>(defmysql mysql-close : _handle -&gt; _void)<br>(defmysql mysql-error : _handle* -&gt; _string)<br><br>(current-mysql-handle (mysql-init))<br><br>(defmysql mysql-real-connect :<br>
&nbsp; _handle* _string _string _string _string _int _string _long -&gt; _data)<br><br>(defmysql mysql-ping : _handle* -&gt; _ok?)<br><br>(defmysql mysql-query : _handle* _string -&gt; _ok?)<br>(defmysql mysql-free-result : _handle* _result -&gt; _void)<br>
(defmysql mysql-store-result : _handle* -&gt; _result)<br>(defmysql mysql-num-fields : _result -&gt; _int)<br>(defmysql mysql-num-rows : _result -&gt; _int)<br>(defmysql mysql-field-count : _handle* -&gt; _int)<br>(defmysql mysql-fetch-row : _result -&gt; (_vector o _string (mysql-field-count)))<br>
(defmysql mysql-fetch-lengths : _result -&gt; (_vector&nbsp; o _long (mysql-field-count)))<br><br><br>;; TEST CODE<br>(define (do-test)<br>&nbsp; (mysql-real-connect &quot;localhost&quot; &quot;root&quot;&nbsp; &quot;PASSWORD&quot; &quot;DATABASE&quot; 0 &quot;&quot; 0)<br>
&nbsp; (mysql-query &quot;select ID, user_login from wp_users&quot;)<br>&nbsp; (printf &quot;You&#39;ve got: ~a&nbsp; columns.\n&quot; (mysql-field-count))<br>&nbsp; (let ([r (mysql-store-result)])<br>&nbsp;&nbsp;&nbsp; (let loop ([i 0] [row (mysql-fetch-row r)])<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (cond (row&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (printf &quot;Row: ~a\n&quot; i)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (printf &quot; ~a\n&quot; row)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (printf &quot;\n&quot;)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (loop (add1 i) (mysql-fetch-row r)))<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (else &#39;done)))))<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp; <br><br><br><br><br><br></span></div></div><br>-- <br>Have an idea for software? &nbsp;I can make it happen - <a href="http://www.ideas2executables.com">http://www.ideas2executables.com</a><br>
My Blog: <a href="http://benjisimon.blogspot.com">http://benjisimon.blogspot.com</a><br>