dotgnu-general
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [DotGNU]InternalCall or: how to call system libs


From: Gopal.V
Subject: Re: [DotGNU]InternalCall or: how to call system libs
Date: Sun, 31 Mar 2002 21:16:39 +0530
User-agent: Mutt/1.2.5i

If memory serves me right, Rhys Weatherley wrote:
> Timo --Blazko-- Boewing wrote:
> 
> > i have read several documentations from the DotGNU project, but so far i
> > have no idea of how to call system libraries.
> > Supposed a library is equally available on all platforms (e.g. some GNU
> > tools/ports) supported by DotGNU (so, a ".dll" on Win32/64 and a ".so"
> > on UN*X :-)), can i do these native system calls directly from a C# lib
> > e.g. from System.x.y?
> 
> 
> Note: pnet's C# compiler doesn't support all of the
> necessary attributes just yet, so it is necessary to
> build such programs with Microsoft's compiler, until
> such time as I can get attributes working (soon).
> Once compiled with Microsoft's compiler, it will run
> on pnet's engine just fine.

        No way !. I can make wrappers work in GNU . But it ain't
pretty and it ain't C#. (Rhys , you're sheilding these people
from the harsh realities of CLR).

        This is an indepth excursion into IL (the real thing).
The pnet's ilasm comes to help if you rrrrrreally want to 
wrap a *few* simple functions. 

Nebies, don't be scared -- this mail will help someone.
If it's not you, please excuse , pardon and forgive me.

        First step -- write your code with a stub normal C# 
function.

1: public class Hello
2: {
3:   static extern int puts(string str);
4:   public static void Main()
5:   {
6:              puts("hello");
7:   }
8: }

        Now compile it using cscc -S option. You get a Hello.il file.
That looks like...

lots of junk above this
-----------------------------------------------------------------------
.class public auto ansi 'Hello' extends ['mscorlib']'System'.'Object'
{
.method private static hidebysig int32 'puts'(class 
['mscorlib']'System'.'String' 'str') cil managed 
{
} // method puts which will be replaced with the Pinvoke decl
.method public static hidebysig void 'Main'() cil managed 
{
        //.entrypoint to be added here
        ldstr   "hello"
        call    int32 'Hello'::'puts'(class ['mscorlib']'System'.'String')
        pop
        ret
        .maxstack 1
} // method Main
--------------------------------------------------------------------
lots of junk below this part


Now add a .entrypoint in the main method. Add a ".module extern 'libc.so.6'"
outside the class below the ".module '<Module>'"
        
        And now add the pinvokeimpl("libc.so.6") stuff to puts...

.method private static hidebysig int32 pinvokeimpl("libc.so.6") 'puts'(class 
['mscorlib']'System'.'String' 'str') cil managed {} // method puts

        now ilasm -o hello.exe hello.il

        Now , wrapping compilcated data types like Structs and Unions of 
C into C# is tough (IMHO). So you could write a small .so or .dll to
wrap the system parts of C like unions ,structs , VA_ARGs , eg I don't 
know how to wrap printf() .

Also you should pass other data structures like Classes as individual 
members -- notable exceptions are the decimal classes and string classes 
which are easily handled . (no more Hjava_lang_String !).

Read pnet/engine/HACKING for the rest of the data type mapping stuff 
(IntPtr,enums etc...) Or ask Rhys. Also Rhys will help you to write 
portable code for PInvoke using his DLLImportMap stuff to use different 
namings like .so,.dll etc..

If you're still reading this, that means you're curious which is a
good thing !. 

Gopal.V
-- 
 The difference between insanity and genius is only measured by success
 //===<=>===\\
|| GNU RULEZ ||
 \\===<=>===//


reply via email to

[Prev in Thread] Current Thread [Next in Thread]