Calling shared lib with "double" not working as expected?

Started by lyntongrice, November 24, 2014, 09:58:21 PM

Previous topic - Next topic

lyntongrice

Hi there,



First off "NewLisp" is so awesome, really liking it.



BTW: I am running it on Red Hat Linux 64 bit machine.



Also, I understand NewLisp deals with integers and floats.....but just curious about "doubles"



Quick question that I hope someone can help me with. So below is a very basic "shared lib":



dummy.h


double doCalc(double x);


dummy.c



#include <stdio.h>
#include <stdlib.h>

double doCalc(double x){
   double y;
   printf("Number passed in: %fn", x);
   y = x * 2;
   printf("Number multiplied by 2 is: %fn", y);
   return y;
}


I compiled this with simple makefile:

CC = gcc

all: libdummy.so

libdummy.so:
$(CC) -m64 -Wall -g -I./ -c -fPIC ./dummy.c -o ./dummy.o
$(CC) -m64 -shared -o ./libdummy.so ./dummy.o -L/usr/lib64

clean:
rm ./*.so


Then I enter newlisp on command line:



newLISP v.10.6.0 64-bit on Linux IPv4/6 UTF-8 libffi, options: newlisp -h



> (import "/home/lynton/Desktop/ffi/libdummy.so" "doCalc")

doCalc@7F5D59D2C57C

> (doCalc 8.7)

Number passed in: 8.700000

Number multiplied by 2 is: 17.400000

4625590882276894310

>





Why would the above return 4625590882276894310 to NewLisp when it should have been "17.4"?



Am I doing something stupid here?



Thanks for the help



Lynton

ryuo

Think about it. You are importing the function without even declaring what the return type and argument types are.



If you have used C a long time, you should recall something called an "implicit function declaration". It is not a good idea to use functions like this, as the C compiler ends up "guessing" the function's prototype. The same problem exists in newLISP.



You must give newLISP the full information about the function. There is no way for newLISP to infer this on its own. After all, newLISP does not parse C headers. newLISP can only detect whether the shared library exists and whether the requested function exists in the library. It cannot automatically determine the return type and argument types of the C function.



If you do not supply the information required, newLISP will just "guess" like the C compiler would in a similar situation. To remedy this situation, the easiest solution is to import the function like so:



(import "/home/lynton/Desktop/ffi/libdummy.so" "doCalc" "double" "double")


After the function name argument, the first is the name of the return type. The remaining arguments at the end of the list are for the argument types. If the function does not take any arguments, then a single argument of "void" should be used.



Hopefully this helps.

Lutz

.... also 4625590882276894310 is the IEEE-754 64 bit float representation of 17.4:


> (get-float (address 4625590882276894310))
17.4
>


Ps: in order to specify types in function imports, your newLISP version must be compiled with libffi support - the simple import without types is present on any version, but has limits when using anything else then 64-bit args, or 32-bits on a 32-bit newLISP version.

lyntongrice

Hi there,



Thanks to the both of you for the feedback on this, I really appreciate it.



Lynton