5,781,349 members and growing! (48 online)
Email Password   helpLost your password?
Platforms, Frameworks & Libraries » Cross Platform » General     Intermediate

C# method calls within Java Program

By KoriFrancis

Using C# from Java through JNI just got a little easier to understand
Java, Windows, Java, Visual Studio, Dev

Posted: 16 Feb 2006
Updated: 16 Feb 2006
Views: 45,416
Bookmarked: 24 times
Announcements
Loading...



Search    
Advanced Search
Sitemap
13 votes for this Article.
Popularity: 3.12 Rating: 2.80 out of 5
4 votes, 30.8%
1
1 vote, 7.7%
2
1 vote, 7.7%
3
1 vote, 7.7%
4
6 votes, 46.2%
5
Note: This is an unedited contribution. If this article is inappropriate, needs attention or copies someone else's work without reference then please Report This Article

Sample Image - javacsharp.jpg

Introduction

Have you ever wanted to (for some reason or another) needed to use C# from within a Java program?
Ever wondered how you could possibly make C# calls from within Java? Well, I try to explain what is needed
in this whole process.

Background

I was working on some Keyboard Hooking problems and found it very easy to develop using C#. The problem was,
that I was trying to develop a solution (originally) for a Java based program. After much Internet searching, I finally
stumbled onto a really good article that started to put the pieces together. The article "Experience in integrating
Java with C# and .NET
" by Judith Bishop, R. Nigel Horspool and Basil Worrall was the insight I needed to start this
project.

That article does show a method to using C# within a Java program, however I didn't find it was easy to understand the
whole process. After I actually had C# working within a Java program, I realized that the process could become a
Codeproject article (my first article).

Using the code


Figure is taken from the article "Experience in integrating
Java with C# and .NET
" by Judith Bishop, R. Nigel Horspool and Basil Worrall

I guess the best way to use this code is to experiment with, use it as a template for a project. I obviously
didn't do anything terribly complicated by just putting up a "Hello World" example, but I wanted people to see
the easiest way possible first. The sample code is simply a console based java program which will show the
"Hello World, from C#" message. I'm also including all the source code and projects in all 4 languages.

Why the need for so many wrappers you may ask? Well, several layers of wrapping are needed because the
DLL produced by compiling a C# program into a library is not compatible with Java's JNI. The double layer of
C++ above is required because the DLL with which the JNI subsystem interacts with has to be static, procedural
code (not object oriented). So, the first layer is essentially C code. Fortunately, static C code will accommodate
(static) pointers to C++ objects. It's doubtful whether the static C code could interact direction with a C# object,
since there are things like garbage collection to consider.

Java Section

I was using Netbeans 4.0 as my main Java IDE at the time, and because of that, the process of using
native code was a little more complicated. The reason of that, is because a Netbeans project wants to
put code inside packages rather than just using the default namespace. The javah console program however
doesn't look at the package and therefore doesn't correctly make the header in the right namespace.
So, as I found out, there's a simple two second fix. Which just requires you edit the generated header
file to correctly make the connection through JNI to the native methods in C++.

Here is the only Java code, which resides in the helloworld package:

public class HelloWorld {
    public native void displayHelloWorld();
    static {
        System.loadLibrary("HelloWorld");
    }
    
    public static void main (String[] args) {
        new HelloWorld().displayHelloWorld();
    }
}

So then, to make this into the header which is needed by the C++ Library, this command needed to be run:

javah -jni helloworld.java

That step produces the following header:

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>

/* Header for class HelloWorld */

#ifndef _Included_HelloWorlds
#define _Included_HelloWorld
#ifdef _cplusplus
extern "C" {
#endif
/*
 * Class:        HelloWorld
 * Method:        displayHelloWorld
 * Signature:    ()V
 */
JNIEXPORT void JNICALL Java_HelloWorld_displayHelloWorld (JNIEnv *, jobject);

#ifdef __cplusplus
}
#endif
#endif

However, if we don't change the generated header then the JNI call will fail as the method has a
different signature due to NetBeans and the package. So the JNIEXPORT line is changed to:

JNIEXPORT void JNICALL Java_helloworld_HelloWorld_displayHelloWorld (JNIEnv *, jobject);

C++ Library

The purpose of the C++ library is to become the JNI Wrapper for the call (through the Managed C++ wrapper) to the endpoint C# code.

#include <jni.h>


// This is the java header created using the javah -jni command.

#include "Java\HelloWorld.h"


// This is the Managed C++ header that contains the call to the C#

#include "MCPP\HelloWorld.h"


// This is the JNI call to the Managed C++ Class

// NOTE: When the java header was created, the package name was not included

//       in the JNI call. This naming convention was corrected by adding the 

//         "helloworld" name following the following syntax: 

//       Java_<package name>_<class name>_<method name>

JNIEXPORT void JNICALL Java_helloworld_HelloWorld_displayHelloWorld(JNIEnv *jn, jobject jobj) {

    // Instantiate the MC++ class.

    HelloWorldC* t = new HelloWorldC();

    // The actual call is made. 

    t->callCSharpHelloWorld();
}

Managed C++ Library

#using <mscorlib.dll>
#using "CSharpHelloWorld.netmodule"

using namespace System;

public __gc class HelloWorldC
{
    public:
        CSharpHelloWorld __gc *t; // Provide .NET interop and garbage collecting to the pointer.

        HelloWorldC() {
            t = new CSharpHelloWorld(); // Assign the reference a new instance of the object

        }
        
     // This inline function is called from the C++ Code

        void callCSharpHelloWorld() {
            t->displayHelloWorld();
        }
};

C# Library

The step that is required for the interaction between Managed C++ and C# is that the CSharpHelloWorld
library be compiled as a .netmodule. To do this, the following command must be run from either the
console or as a post-build event within the C# project (I streamlined the process by using post-build):

csc /debug /t:module "$(OutDir)\$(ProjectName).dll"
There is barely any code in this project, as I only wanted to show the simplest example possible.
And what, my friends, is more simple than 'HelloWorld'?
using System;

public class CSharpHelloWorld
{
    public CSharpHelloWorld() {}

    /// <summary>

    /// displayHelloWorld will be the method called from within java.

    /// </summary>

    public void displayHelloWorld() 
    {
        Console.WriteLine("Hello World, from C#!");
    }
}

Points of Interest

Working with Java JNI is quite a pain, especially by using netbeans as an IDE. Hopefully, I've given you
some insight as to what to expect at the different steps of this process. I must have hit every single
roadblock in this project, and taken the time to look up what was needed.

History

Version 1.0 - First Release!

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

About the Author

KoriFrancis


I'm current a 3rd year Computer Engineering Technology : Software Developer student at St. Lawrence College in Kingston, Ontario.

I usually get myself into some of the more cool projects like neural nets or cross platform applications.
Occupation: Web Developer
Location: Canada Canada

Other popular Cross Platform articles:

  • Introduction to Mono - Your first Mono app
    The first in a series of articles about Mono. This article explains how to install Mono and shows how to compile your first Cross Platform application.
  • MONO: an alternative for the .NET framework
    This article presents possibilities for development of .NET applications running on operating systems other than Windows, using the MONO platform. Advantages and challenges will be presented. Also presented are some common issues encountered while developing applications using the .NET technology.
  • Embed ActiveX controls inside Java GUI
    With this your Java projects can take advantage of ActiveX controls and Office documents such as spreadsheets, charts, calendars, word processors, specialized graphics, and many more.
  • Introduction to Mono - ASP.NET with XSP and Apache
    The second article in a series of articles about Mono. This article explains how to host and serve ASP.NET Web Applications and Web Services on Linux using XSP and Apache with the help of Mono.
  • Phalanger, PHP for .NET: Introduction for .NET developers
    Phalanger is a PHP language compiler for the .NET Framework which introduces PHP as a first-class .NET citizen.
Article Top
Sign Up to vote for this article
You must Sign In to use this message board.
FAQ FAQ Noise ToleranceSearch Search Messages 
 Layout  Per page   
 Msgs 1 to 25 of 33 (Total in Forum: 33) (Refresh)FirstPrevNext
Generaldoes this source and description work for me its not kindly helpmemberG.Makesh0:09 19 Nov '07  
QuestionC# with reference to 3rd party DLLsmemberLee Rong8:56 13 May '07  
AnswerRe: C# with reference to 3rd party DLLsmemberabdulcalicut0:48 12 Jun '07  
AnswerRe: C# with reference to 3rd party DLLsmemberabdulcalicut1:29 14 Jun '07  
GeneralRe: C# with reference to 3rd party DLLsmemberJorge M. R. Santos11:25 16 Nov '07  
GeneralRe: C# with reference to 3rd party DLLsmemberLarsKongo5:06 6 Mar '08  
GeneralCould not make it work!memberfrankmt16:49 26 Mar '07  
GeneralVisual studio 2005memberJonathan120521:29 14 Sep '06  
GeneralRe: Visual studio 2005memberRaj24110:57 27 Dec '06  
GeneralRe: Visual studio 2005memberaznawm12:05 9 May '07  
GeneralReference the namespacememberseralav23:29 13 Sep '06  
GeneralRe: Reference the namespacememberJorge M. R. Santos6:45 10 Oct '07  
QuestionOther compiling problems [modified]membercaptainjapan11:12 22 Jun '06  
AnswerRe: Other compiling problemsmemberdanmat22:31 28 Jun '06  
QuestionCompiling Problemsmemberdanmat4:59 22 Jun '06  
GeneralObject-Oriented JNI (low-level) for DOTNET 1.0.03 ReleasedmemberVitaly Shelest1:57 25 Apr '06  
GeneralLoading managed dllsmemberjladd111:00 12 Apr '06  
GeneralRe: Loading managed dllsmemberRajesh Turlapati7:36 17 Nov '06  
GeneralRe: Loading managed dllsmemberjladd111:34 20 Nov '06  
GeneralRe: Loading managed dllsmemberRajesh Turlapati6:41 27 Nov '06  
QuestionHow to pass a String parametermembermvmundlye20:43 12 Mar '06  
AnswerRe: How to pass a String parametermemberrskousen13:29 23 Mar '06  
GeneralRe: How to pass a String parametermemberRacano5:51 23 May '07  
GeneralRe: How to pass a String parametermemberchapsi11:46 26 Sep '07  
GeneralGood work!memberSantosh K Sahoo3:50 22 Feb '06  

General General    News News    Question Question    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

PermaLink | Privacy | Terms of Use
Last Updated: 16 Feb 2006
Editor:
Copyright 2006 by KoriFrancis
Everything else Copyright © CodeProject, 1999-2009
Java | Advertise on the Code Project