Re: [Mono-dev] Platform independence of mono assemblies
Hi Jonathan, thank you very much for the answer! Here are a couple of follow-up questions: On 05/19/2011 03:46 PM, Jonathan Pryor wrote: On May 18, 2011, at 5:53 PM, Christian Krause wrote: As far as I know this decision was based on a statement from the mono developers ([1]), that although the C# assemblies are currently architecture independent, it can not be guaranteed that they will be forever. That is why Fedora treats C# assemblies as arch-dependent files and so they are installed on multi-arch x86_64 systems into /usr/lib64. Not exactly. As Miguel mentioned, mono at the time required that AOT-compiled shared libraries be placed next to the assembly, e.g. for mscorlib.dll the AOT-compiled mscorlib.dll.so must be in the same directory. So to summarize: - C# / CLI assemblies are itself platform independent - the pre-compiled AOT ELF binaries are platform dependent (but are not in wide-spread use and there may be other options where to place them in the future) - interfacing native code can be done platform dependent or independent (see below) However, no Linux distribution actually uses AOT-compiled assemblies (that I know of, anyway). Hence my quote: the feature is there, but it's rarely (never?) used, so using this as a reason to be different from openSUSE, Debian, Ubuntu, and the default build setup seems like chasing the perfect at the expense of the good. ;-) Just to remove all uncertainties: Is it the view of the mono developers, that the standard libraries from the mono project interfacing the native libraries in an platform-independent way? If there would be a platform dependency left by accident, would this be considered a valid bug report? Would you also agree, that if 3rd party projects use platform-dependent assemblies this should be treated as a bug which has to be fixed? As far as I know, the C# assemblies are indeed architecture independent (as defined by the CIL standard). There may be some corner cases where it is possible to explicitly write arch-dependent code, but these may be treated as bugs in the projects. It _is_ possible to have platform specific assemblies. Not because the IL is platform specific (as you note), but because of Platform Invoke [1], which allows ~direct invocation of native code. Managed code may thus embody platform specific assumptions. For example, consider nanosleep(2) [2]: Yes, that's aligned with my understanding of the various ways to interface native code ( http://www.mono-project.com/Interop_with_Native_Libraries ) and their respective levels of architecture independence. Best regards, Christian ___ Mono-devel-list mailing list Mono-devel-list@lists.ximian.com http://lists.ximian.com/mailman/listinfo/mono-devel-list
[Mono-dev] Alignment issue when interoperate with native code
Hi, During debugging a C# wrapper for a C-library I have stumbled over an unexpected alignment issue in mono / C#: It looks like that the internal alignment of data structures deviates on 32-bit X86 systems from the standard ELF alignment. I've created a minimal testcase which can be downloaded from here: http://chkr.fedorapeople.org/mono-alignment/ 1. libalignmenttest.c: a C-library containing a function testfunc which returns a structure containing a double: struct t1 { int i1; double d1; }; The function sets the values always to i1 = 1234 and d1 = 1.1. 2. test.cs: a C# file which calls testfunc from the C-library: Since all of the variables of the t1 structure are blittable types, it should be possible just to define the structure in C# and declare the appropriate function using DllImport. http://www.mono-project.com/Interop_with_Native_Libraries : [...] so if an unmanaged function returns a pointer to a structure, IntPtr must be used for safe code, or a pointer to the structure can be used for unsafe code.[...]. I have chosen the 2nd choice: struct t1 { public int i1; public double d1; } [DllImport(libalignmenttest)] unsafe public static extern t1* testfunc(); 3. Running the test: $ gcc -Wall -Werror -o libalignmenttest.so -shared -Wl,-soname,libalignmenttest.so libalignmenttest.c $ gmcs -unsafe test.cs $ mono ./test.exe i1: 1234 d1: 5.35799274627359E-313 $ So the value of d1 is messed up. It looks like that C# aligns double data types on 8-byte boundaries but linux ELF ABI defines an 4-byte alignment which is used in the native library. If I restrict the alignment of C# to 4-byte alignment by adding [StructLayout (LayoutKind.Sequential, Pack=4)], it works fine. 4. Definition of C# / ELF alignment: The X86 ELF ABI defines that double values should be 4-byte aligned X86 ELF ABI: http://refspecs.freestandards.org/elf/abi386-4.pdf , Figure 3-1. The ECMA CLI standard defines the alignment so: http://www.ecma-international.org/publications/files/ECMA-ST/ECMA-335.pdf , 12.6.2 [...] and int64, unsigned int64, and float64 start on an address divisible by 4 or 8, depending upon the target architecture. [...] It is strongly recommended that float64 be aligned on an 8-byte boundary, even when the size of native int is 32 bits.. 5. My questions: a) Is it the intended behavior of mono on X86-32 systems that the internal representation of struct data types uses 8-byte alignment for double types even if this deviates from the ELF alignment rules? b) Since the same problem happens with the 64bit integer type (long long in C, long in C#) this would mean, that as soon as 64 bit data types are involved, structures can never be transferred between native code and C# using pointers to C# structures and it is strictly required to use a technology which marshals them correctly (either using IntPtr and Marshal.PtrToStructure or use C# classes as return values for the native function where the marshalling seems to be done implicitly.) c) The ECMA CLI standard recommends explicitly for float64 to use an 8-byte alignment and so the implementation seems to follow the standard here. But what about the int64 data type? The specification states only, that it should 4- or 8-byte aligned, [...] depending upon the target architecture and on X86-32 systems that target architecture does not require an 8-byte alignment for 64bit integers. Is it intended that int64 is also 8-byte aligned? It would be great if someone could confirm whether my findings are correct. ;-) Thank you very much in advance! Best regards, Christian ___ Mono-devel-list mailing list Mono-devel-list@lists.ximian.com http://lists.ximian.com/mailman/listinfo/mono-devel-list