|
|||||||||||||||||||||||
|
|||||||||||||||||||||||
|
Announcements
Chapters
Services
Feature Zones
|
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
IntroductionHave you ever wanted to (for some reason or another) needed to use C# from within a Java program? BackgroundI was working on some Keyboard Hooking problems and found it very easy to develop using C#. The problem was, That article does show a method to using C# within a Java program, however I didn't find it was easy to understand the Using the code
I guess the best way to use this code is to experiment with, use it as a template for a project. I obviously Why the need for so many wrappers you may ask? Well, several layers of wrapping are needed because the Java SectionI was using Netbeans 4.0 as my main Java IDE at the time, and because of that, the process of using Here is the only Java code, which resides in the
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
JNIEXPORT void JNICALL Java_helloworld_HelloWorld_displayHelloWorld (JNIEnv *, jobject);
C++ LibraryThe 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# LibraryThe step that is required for the interaction between Managed C++ and C# is that the 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 InterestWorking with Java JNI is quite a pain, especially by using netbeans as an IDE. Hopefully, I've given you HistoryVersion 1.0 - First Release!
|
||||||||||||||||||||||