Re: Pass C double to Eu shared library
- Posted by jimcbrown (admin) May 12, 2012
- 1510 views
Jerome said...
I have a shared library made with EU 4 that I would like to access from C by passing an array of doubles. Looking through the manual I found this:
Euphoria shared dynamically loading library can also be used by C programs as long as only 31-bit integer values are exchanged. If a 32-bit pointer or integer must be passed, and you have the source to the C program, you could pass the value in two separate 16-bit integer arguments (upper 16 bits and lower 16 bits), and then combine the values in the Euphoria routine into the desired 32-bit atom.
Is there a clean way to do this?
My current code is essentially the following:
-- Eu Code export function MyFunc(sequence x) ? x end function
// C Code extern MyFunc(double x[]) int main() { double x[4] = {1.1,2.2,3.3,4.4}; MyFunc(x); return 0; }
Thanks,
Ira
On the Euphoria side,
-- Eu Code export function MyFunc(integer a, integer b, integer len) -- preamble to handle conversion atom p = (a * 65536) + b sequence x = {} for i = 0 to (len-1)*8 by 8 do sequence d = peek({p+i, 8}) x &= float64_to_atom(d) done -- end preamble ? x end function
(Sadly, 4.0 seems to lack a peek_float64_array(). Otherwise we could do this:
-- Eu Code export function MyFunc(integer a, integer b, integer len) -- preamble to handle conversion atom p = (a * 65536) + b sequence x = peek_float64_array(p, len) -- end preamble ? x end function
)
On the C side,
// C Code extern void MyFunc(int a, int b, int len) int main() { double x[4] = {1.1,2.2,3.3,4.4}; intptr_t d, a, b; d = (intptr_t)x; b = d & 0xFFFF; a = d & 0xFFFF0000; a = a >> 16; MyFunc(a, b, 4); return 0; }
Or even,
// C Code extern void MyFunc(int a, int b, int len) void MyFuncWrapper(double x[], int len) { intptr_t d, a, b; d = (intptr_t)x; b = d & 0xFFFF; a = d & 0xFFFF0000; a = a >> 16; MyFunc(a, b, 4); } int main() { double x[4] = {1.1,2.2,3.3,4.4}; MyFuncWrapper(x, 4); return 0; }