Replying to myself with more information...
Dan Muller s8ctxw402-at-sneakemail.com |RDNZL-devel/via Sneakemail| wrote:
Edi Weitz edi-at-agharta.de |RDNZL-devel/via Sneakemail| wrote:
I was mistaken when I said that the float coercion is working. After struggling with Mesh.Cylinder to no avail, I wrote a very small test assembly in C#:
[code elided]
(I'm using VS 2005, thus .NET 2.0. Not that it should make much difference.)
Hrrrm. Since you're using Managed C++, I'm not able to compile the RDNZL DLL. The solution converts up to VS8 OK. But, as you probably know, Managed C++ was replaced by C++/CLR. The conversion adds the necessary compiler option to support the old syntax, but the multi-threaded run-time library setting is incompatible with it (Configuration Properties/C++/Code Generation/Runtime library). Oh well. Just providing this as an FYI.
Yop is used as a sanity check, and it works. I can successfully call ShowDouble with *c-d-f-t-s* nil. I can call both ShowDouble and ShowSingle with *c-d-f-t-s* t, but *both* show an incorrect result.
Delving deeper, I find that with *c-d-f-t-s* t, [ToString (box 5.5)] return "0", and [ToString (box 5.4)] returns something ugly that isn't 5.4. In BOX*, you call MakeDotNetContainerFromFloat, but what you actually end up passing it is a double. This is where a down-conversion needs to happen. Poking around in the LW FLI documentation, I eventually figured out a simple change that fixes this.
In port-lw.lisp, FFI-MAP-TYPE, change :float to :lisp-float. This causes any Lisp float type (only double on Windows!) to be converted to a single float in FLI calls. So this is how we get LispWorks to do the implicit down-conversion for us when calling foreign functions that take singles.
Another good test is (box (unbox 5.4)). This didn't work before, and now it does.
This doesn't fix the overall problem yet, though. This test, using the assembly I gave in the previous email, still gives bad results:
(eval-when (:compile-toplevel :load-toplevel) (asdf:operate 'asdf:load-op :rdnzl)) (use-package :rdnzl)
;; This approach doesn't work ;(import-types "ClassLibrary1")
; Do this instead? (import-type "ClassLibrary1.Class1" (load-assembly "ClassLibrary1"))
(use-namespace "ClassLibrary1") (enable-rdnzl-syntax) (defun rtest () [Yop "Class1"] [ShowDouble "Class1" 1.0] ; correct [ShowDouble "Class1" 7.267] ; correct (let ((*coerce-double-floats-to-single* t)) (declare (special *coerce-double-floats-to-single*)) [ShowDouble "Class1" 1.0] ; shows incorrectly [ShowDouble "Class1" 7.267] ; shows incorrectly [ShowSingle "Class1" 1.0] ; shows incorrectly [ShowSingle "Class1" 7.267])) ; shows incorrectly
So I'm still working on it. Probably has to with the way that return values are handled...