I need to 'forward function call' for a language binding I'm writting (ObjectiveC-.NET)
I have a problem with _builtin_return which is reproduced in the simple attached sample.
 
While it works well with integeter, char, type of register size or less, I have problem with bigger values, such as float, double, struct.....
 
anyone could shed some light?
 
#define DLL_EXPORT __declspec(dllexport) __cdecl

// gcc -shared -o simple-native.dll simple.c

static char do0(int type)
{
        return 'a';
}
static const char * const buf1 = "lalali";
static const char * const do1(int type)
{
        return buf1;
}
static float do2(int type, float f1, float f2)
{
        return f1 * f2;
}
static double do3(int type, double d1, double d2)
{
        return d1 * d2;
}
struct Foo
{
        int f1;
        short f2;
        double f3;
};
static double do4(int type, struct Foo foo)
{
        return foo.f1 * foo.f2 * foo.f3;
}
static struct Foo do5(int type, struct Foo foo1, struct Foo foo2)
{
        foo1.f1 *= foo2.f1;
        foo1.f2 *= foo2.f2;
        foo1.f3 *= foo2.f3;
        return foo1;
}
static const char * const do6(int type, struct Foo foo1)
{
        return buf1;
}


DLL_EXPORT void forward(int type)
{
        void (*fct)();
        
        switch(type)
        {
                case 0:
                        fct = (void (*)()) &do0;
                        break;
                case 1:
                        fct = (void (*)()) &do1;
                        break;
                case 2:
                        fct = (void (*)()) &do2;
                        break;
                case 3:
                        fct = (void (*)()) &do3;
                        break;
                case 4:
                        fct = (void (*)()) &do4;
                        break;
                case 5:
                        fct = (void (*)()) &do5;
                        break;
                case 6:
                        fct = (void (*)()) &do6;
                        break;
        }
        
        void* args = __builtin_apply_args();
        __builtin_return( __builtin_apply(
                fct, 
                args, 
                10 * sizeof(int) 
        ));
}
using System;
using System.Runtime.InteropServices;

// csc /nologo /out:simple.exe Simple.cs && simple
class Simple
{
        [Serializable]
        [StructLayout(LayoutKind.Sequential)]
        public struct Foo
        {
                public int f1;
                public short f2;
                public double f3;
                
                public Foo(int a1, short a2, double a3)
                {
                        f1 = a1;
                        f2 = a2;
                        f3 = a3;
                }
                public override string ToString()
                {
                        return string.Format("Foo{{{0}, {1}, {2}}}", f1, f2, 
f3);
                }
        }
        
        [DllImport("simple-native", EntryPoint="forward", CharSet = 
CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
        [return: MarshalAs(UnmanagedType.U1)]
        static extern char do0(int type);
        public static char do0() { return do0(0); }
        
        [DllImport("simple-native", EntryPoint="forward", CharSet = 
CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
        static extern string do1(int type);
        public static string do1() { return do1(1); }
        
        [DllImport("simple-native", EntryPoint="forward", CharSet = 
CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
        static extern float do2(int type, float f1, float f2);
        public static float do2(float f1, float f2) { return do2(2, f1, f2); }
        
        [DllImport("simple-native", EntryPoint="forward", CharSet = 
CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
        static extern double do3(int type, double d1, double d2);
        public static double do3(double d1, double d2) { return do3(3, d1, d2); 
}
        
        [DllImport("simple-native", EntryPoint="forward", CharSet = 
CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
        static extern double do4(int type, Foo foo);
        public static double do4(Foo foo) { return do4(4, foo); }
        
        [DllImport("simple-native", EntryPoint="forward", CharSet = 
CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
        static extern Foo do5(int type, Foo foo1, Foo foo2);
        public static Foo do5(Foo foo1, Foo foo2) { return do5(5, foo1, foo2); }
        
        [DllImport("simple-native", EntryPoint="forward", CharSet = 
CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
        static extern string do6(int type, Foo foo1);
        public static string do6(Foo foo1) { return do6(6, foo1); }
        
        
        public static void Main()
        {
                Console.WriteLine(do0());
                Console.WriteLine(do1());
                Console.WriteLine(do6(new Foo(10, 11, 12)));
                Console.WriteLine(do2(1,2));
                Console.WriteLine(do3(3,4));
                Console.WriteLine(do4(new Foo(1,2,3)));
                Console.WriteLine(do5(new Foo(1,2,3), new Foo(4,5,6)));
        }
}
_______________________________________________
Discuss-gnustep mailing list
[email protected]
http://lists.gnu.org/mailman/listinfo/discuss-gnustep

Reply via email to