How to call API in Unix from C#?

G

Guest

I was told that Unix API can only be called using C++, ATL and MFC. However,
I was also told that C# can do that through Pinvoke to a DLL that interfaces
with the Unix API. Can someone direct me to some good article to read up on
this?

Basically, I'm looking a possible project that has a Window client but needs
to get information from Unix side sometime by calling some API in Unix.

Many thanks in advance,
Alpha
 
W

Willy Denoyette [MVP]

Alpha said:
I was told that Unix API can only be called using C++, ATL and MFC.
However,
I was also told that C# can do that through Pinvoke to a DLL that
interfaces
with the Unix API. Can someone direct me to some good article to read up
on
this?

Basically, I'm looking a possible project that has a Window client but
needs
to get information from Unix side sometime by calling some API in Unix.

Many thanks in advance,
Alpha

You can only call API's (using PInvoke) on the system where your application
is running, you can never 'call API's' across systems. All you can do is use
some form of inter-process/inter-systems communication using sockets.


Willy.
 
J

Joshua Flanagan

Is the "unix api" running on a different machine than your C#
application? In this case, you would use whatever protocol the remote
API requires (sockets/tcp/http).

Or do you mean the calling the Windows POSIX support DLLs or Windows
Services For Unix add-on functionality from a C# application? You should
be able to do this via PInvoke if you know the DLL and function names.

I am assuming your C# application is running on a Windows computer, and
not a Unix computer compiled with MONO.
 
W

Willy Denoyette [MVP]

It depends on what you call an API, an API is a pure local interface, that
is, a program or program module (DLL's, shared libraries ..) calls functions
contained in another module through an API, but a program module cannot
directly call functions in a module that is not local to the calling module
(f.i. located on a remote system). When the calling and called modules are
both local, one can call another through an API, provided they conform to
the same API requirements. Managed code like C# can call a non managed API
through PInvoke (the runtime interop layer) provided the API is a C style
API.
However, if the called module is "remote", your only option to call it's
"functions" (API's), is by using a network based "remote procedure call"
protocol. You could develop your own protocol over tcp sockets, you could
use one of the (commercially) available RPC products like CORBA or you could
expose your API's as Webservices running on the remote system. But, again
all depends on what you are exactly looking for.

Willy.
 
G

Guest

Hi Joshua, You're absolutely correct about the my C# application running on a
Window machine and the other Unix API is running on a Unix server. I need to
wirte some code for importing some information retrieved from the Unix by
placing some calls to the Unix server. What are those "Unix add-on
functionality from a C# application" that you're referring to? Can you
recommend any good reading on doing something like this? Are there certain
..net library calls that I can utilize for communicating with Unix?

Thanks,
Alpha
 
J

Joshua Flanagan

What are those "Unix add-on functionality from a C# application" that
you're referring to?

I was referring to the Windows Services For Unix add-on. It has nothing
to do with C#, but I was suggesting you might be able to call them from
C#. But you aren't trying to call Unix functionality on a Windows
machine, so that is probably not relevant.
Are there certain .net library calls that I can utilize for
communicating with Unix?

If you are just trying to make remote networking calls to a unix service
(or any remote network service), you will need to use the
System.Net.Sockets classes (TcpClient if possible, or Socket if you need
tighter control).
 
G

Guest

Thank you Joshua. I think what I need is System.Net.Sockets classes, as you
suggested. I will look into that.

Many thanks and happy holiday,
Alpha
 
G

Guest

In this application, the windows side would be the TCPServer, created under
the System.net.sockets. Will the Unix side be able to send me request? I
mean, is there a way for Unix to do the socket programming like what I'll be
doing on the Windows side?

Basicly, I need to exchange data with the Unix side of program. Sometimes,
requesting but most of the time answering and giving data from my side. I
just want to make user that this can be done.

Thanks,
Alpha
 
A

Andnas

Wanted to know if you were able to solve the problem ?, if so how cause I am
also looking for a similar solution
 
M

Michael B. Trausch

Wanted to know if you were able to solve the problem ?, if so how
cause I am also looking for a similar solution

APIs can be called via the DllImport attribute within a class. For
example (tested on Mono, on Ubuntu):

using System;
using System.Runtime.InteropServices;

public sealed class UnixFunctionCalls {
[DllImport("libc.so.6")] // UNIX uses .so.* not .dll
private static extern void exit(int status);

[DllImport("libc.so.6")]
private static extern int abs(int num);

public static int Main(string[] args) {
int x = -20;
int y = UnixFunctionCalls.abs(x);

Console.WriteLine("Original: {0}, New: {1}", x, y);

// Use native exit call instead of returning from main.
UnixFunctionCalls.exit(0);

// Also include a return statement since the compiler will
// otherwise complain (because we're supposed to return int).
return(0);
}
}

You can do this for any C library that exists in the system, but you
have to know the name of the C library and you have to be able to put
together a prototype for the function. I am not entirely clear, for
example, how one would use libc's printf() function from C# (not that I
know of any reason why anyone would *want* do to that). Running this
on my system yields:

Tuesday, 2008-Oct-14 at 12:20:20 - mbt@zest - Linux v2.6.27
Ubuntu Intrepid:[1-30/5223-0]:test> ./UnixFunctionCalls.exe
Original: -20, New: 20

Tuesday, 2008-Oct-14 at 12:20:22 - mbt@zest - Linux v2.6.27
Ubuntu Intrepid:[1-31/5224-0]:test>

This demonstrates that the call to libc's abs() function worked as
expected.

You'll want to read the Interop with Native Libraries page on the Mono
wiki, too, for quirks, details, and more, which is relevant for
working on UNIX-like systems with a CLR:

http://www.mono-project.com/Interop_with_Native_Libraries

My understanding is that you can do this on Windows for any DLL whose
name and entrypoint you know, as well. For example, you can call
UNIX-like APIs using the Cygwin DLL on a Windows system.

HTH,
Mike
 
A

Andnas

Thanks Mike, I agree to this solution if the calling and called API's are in
similar environments/server. What if the "libc.so" library is on a UNIX
server...How do you call an api and get a return value if its on different
machine.
 
A

Andnas

Lets say, I have set of routines built and running on UNIX..say some C++
libraries. If we need to build a .NET GUI which needs to invoke these
libraries and execute some function in these libraries, which are sitting on
UNIX. One of the options is to expose the routines as a webservice...but
without that...is there some combination of Socket programming in .NET with
some interop programming....etc..

a simple example would be say...there is a unix function which is adding 2
integers and returning the sum...i need to build a UI in C# where these 2
integers can be passed, invoke the UNIX function and return the value
back...something like that.
 
M

Michael B. Trausch

Lets say, I have set of routines built and running on UNIX..say some
C++ libraries. If we need to build a .NET GUI which needs to invoke
these libraries and execute some function in these libraries, which
are sitting on UNIX. One of the options is to expose the routines as
a webservice...but without that...is there some combination of Socket
programming in .NET with some interop programming....etc..

a simple example would be say...there is a unix function which is
adding 2 integers and returning the sum...i need to build a UI in C#
where these 2 integers can be passed, invoke the UNIX function and
return the value back...something like that.

Alright. If you're not using the CLI on the UNIX machine, then you
have to use some form---any form---of networked IPC. The way _I_ would
probably do it is to create a wrapper for the library in C++ (if the
library is a C++ library) and have that wrapper listen on a socket. Of
course, you'll have to handle authentication on the wrapper in some
form or another, but that's going to be for you to specify how to
handle.

On the .NET side, then, you'd simply have a class that would wrap the
calls to the socket on the UNIX machine, and expose the API calls as
method calls in a class.

You could use a Web service, too, if you want, but depending on what
functionality you're actually going after, that might be overkill.
Then again, it might not.

--- Mike
 
M

Michael J. Ryan

What you are looking for Unix data, you may want to look at Mono.Unix
namespace for your mono port...
 
M

Michael J. Ryan

A webservice on the Unix system is probably the easiest route.

Alternatively, you could have a background process on the unix box running via
mono, with .Net Remoting (this limits the types you can safely send back and
forth).

Lastly, a plain/custom socket service could be used as well..

Without more specifics, its' hard to say... there is no "built in" PInvoke for
remote libraries (ala DOM/COM+)... you may want to look into various CORBA
libraries, as this may also provide the functionality you are looking for.

Me, I would probably go with the .Net remoting route, with Mono on the unix
server, and .Net on the windows side, with the client/server defined, and in a
common dll that gets deployed to both.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top