|
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
