Click here to Skip to main content
Click here to Skip to main content

C# method calls within a Java program

By , 16 Feb 2006
 

Sample Image - javacsharp.jpg

Introduction

Have you ever (for some reason or other) needed to use C# from within a Java program? Ever wondered how you could possibly make C# calls from within Java? Well, I will 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 it 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 use 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

This 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 it, and 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 four 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 directly 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 for that is because a Netbeans project wants to put code inside packages rather than just use 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 to 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:
        // Provide .NET interop and garbage collecting to the pointer.
        CSharpHelloWorld __gc *t;
        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, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

KoriFrancis
Web Developer
Canada Canada
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.

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
QuestionAny simple solution for Java program call C# DLL ?memberkaccy_oon14-Jan-10 14:22 
Any simple solution for Java program call C# DLL ?
Generaljni4net [modified]memberZamboch4-Nov-09 10:25 
I am author of http://jni4net.sf.net/, open source intraprocess bridge between JVM and CLR. It's build on top of JNI and PInvoke. No C/C++ code needed. I hope it will help you.
modified on Thursday, April 22, 2010 2:52 PM

GeneralC++ class compilation errormembershahnawaz.patel25-Oct-09 1:53 
Hi,
 
I am not able to compile c++ class
 
I am able to do the following steps
1. C# sample compile -- Generated .netmodule file with the help of following command
 
csc /debug /f:module FileName.cs
 
2. Managed C++ compile -- command used
cl /LD HelloWorldManaged.cpp /clr:oldSyntax
generate dll file
 
3. java file compile -- class file and header file created
 
4. when i am compiling c++ file with following command

cl /LD HelloWorld.cpp /link HelloWorldManaged.dll
 
I am getting following error
 
HelloWorldManaged.dll : fatal error LNK1302: only support linking safe .netmodules; unable to link i
jw/native .netmodule
 
Can anybody help me on this
Questionwhere's the dll come from?membermaul_oke18-Aug-09 22:23 
hi, i built the code from source but it won't work
even if i change the .dll from the demo with the dll built from the C# on the source it won't work
the dll i built from source is not the same size as in demo. don't know why..
 
when i run the jar using dll from source, this warning appear:
Exception in thread "main" java.lang.UnsatisfiedLinkError
.displayHelloWorld()V
at helloworld.HelloWorld.displayHelloWorld(Native
at helloworld.HelloWorld.main(HelloWorld.java:23)
 
does anyone know why it won't work?
AnswerRe: where's the dll come from?membermacambabun13-May-13 21:27 
yeah i am also. I was newbie in java wrapper, anyone can help us????? Frown | :( Frown | :( Frown | :( Frown | :( Frown | :( Frown | :( :(
QuestionHow can I call java class with in C#memberHari Om Prakash Sharma18-Mar-09 0:41 
By using the same logic, how can I call java classes with in c# code?
 

First and the Foremost: FIGHT TO WIN


MySite:
HariOmPrakash.InFo

Generaldoes this source and description work for me its not kindly helpmemberG.Makesh18-Nov-07 23:09 
does this source and description work for me its not kindly help .iam working with .net2.0 even if i barely dowload the attached source and try running its not working
QuestionC# with reference to 3rd party DLLsmemberLee Rong13-May-07 7:56 
Hi all,
I have managed to execute a simple C# program in Java using the given example and the document “Experience with integrating Java with new technologies: C#, XML and web services”. However, now I need to reference some other 3rd party DLLs within the C# code. I can compile everything successfully under Visual Studio. However when I try to run the program under Java, it gives me an error. The error message does not tell me much about what is wrong, but I am sure it has something to do with the referencing of DLLs in C#, because once I remove that, it all works fine again. So could anyone give me some recommendation as how I can include the 3rd party DLLs with this?
 
Cheers,
 
Lee

AnswerRe: C# with reference to 3rd party DLLsmemberabdulcalicut11-Jun-07 23:48 

 
Hi Lee.
 
Did u get this solution. I face same issue as u mentioned above. ie when i refering a external dll to my c# application, and trying to call this application from JAVA through JNI getting error. But when i remove the dll reference from application ,it work fine.
 
If u able find this solution please sent me...
 
my id is mailtoabdul@gmail.com
 
Regards
Abdul D'Oh! | :doh:
AnswerRe: C# with reference to 3rd party DLLsmemberabdulcalicut14-Jun-07 0:29 
Hi I got the solution..
 
U simply put the 3rd party DLLs into System32 folder ie c:\Windows\system32.
 
Hope this will help u..
 
Please let me knoe if any concerns
 
Regards
Abdul
GeneralRe: C# with reference to 3rd party DLLsmemberJorge M. R. Santos16-Nov-07 10:25 
I'm running into the same problem and placing the library in the System32 folder is not solving it... Whenever I call the 3rd Party dll I get:
 
#
# An unexpected error has been detected by Java Runtime Environment:
#
# Internal Error (0xe0434f4d), pid=3052, tid=372
#
# Java VM: Java HotSpot(TM) Client VM (1.6.0_02-b06 mixed mode, sharing)
# Problematic frame:
# C [kernel32.dll+0x12a5b]
#
# If you would like to submit a bug report, please visit:
# http://java.sun.com/webapps/bugreport/crash.jsp
#
(etc...)
GeneralRe: C# with reference to 3rd party DLLsmemberLarsKongo6-Mar-08 4:06 
Did you ever find a solution to this problem?
GeneralRe: C# with reference to 3rd party DLLsmemberBonorenofu98726-Aug-09 11:36 
I have found a soluction, but it's really tricky.
Basically:
1. Load the DLL:
Assembly^ dll = Assembly::LoadFrom("MyDLL.dll");
2. Create object:
Object^ myObj = dll->CreateInstance("MyNamespace.MyClass");
3. Call method:
myObj->GetType()->InvokeMember(
"myMethod",
static_cast(BindingFlags::DeclaredOnly | BindingFlags::Public | BindingFlags::NonPublic | BindingFlags::Instance | BindingFlags::InvokeMethod),
nullptr,
myObj,
methodParams
);
GeneralRe: C# with reference to 3rd party DLLsmemberDealie30-Apr-13 6:30 
Hi,
 
Check this out: http://www.javonet.com if you have non-commercial project it's free to use and it solves all the issues with loading third-party libraries from GAC or local directory, you can even subscribe events and java app with WPF interface Big Grin | :-D
 
If you have a commercial projects then maybe it's worth to pay and save development time?
 
Regards,
Przemek
GeneralCould not make it work!memberfrankmt26-Mar-07 15:49 
Hi,
 
Im trying to make the article code work, but I couldnt make it.
In my version, when I try to create the C# object, in
 
t = new CSharpHelloWorld(); // Assign the reference a new instance of the object
 
the JVM throws an error.
 
Does anybody know how to solve this problem?
 
Thanks in advance.
 
Francisco
GeneralVisual studio 2005memberJonathan120514-Sep-06 20:29 
Can anyone get it to work in Visual studio 2005. I had no problem getting every thing to work in 2003 but I can't compile CPPHelloWorld in 2005.
GeneralRe: Visual studio 2005memberRaj241126-Dec-06 23:57 
Did you find the way to create a .NETMODULE in 2005?
GeneralRe: Visual studio 2005memberaznawm9-May-07 11:05 
For VS 2005 you need to type this in the command line:
 
csc /debug /t:module /out:FileName.dll SourceCode.cs
 

Note: make sure that your .dll and .cs file is together.
 
And if it is possible could you guys put how you manage your C++ code in Visual Studio 2005 because it is supposedly very different from 2003. I'm stuck at that part now. Thank you.
GeneralReference the namespacememberseralav13-Sep-06 22:29 
Hi, when the netmodule have a definition of namespace, in the wrapper done in c++ ,How I can to reference an object of inside this namespace?
 
I tried:
 
(namespace).(class_name)^ name= gcnew (namespace).(class_name)();
(namespace)->(class_name)^ name= gcnew (namespace)->(class_name)();
 
but it not works.
GeneralRe: Reference the namespacememberJorge M. R. Santos10-Oct-07 5:45 
I think what you need to do is to reference it as you would a c++ class within a namespace.
 
(namespace)::(classname)
QuestionOther compiling problems [modified]membercaptainjapan22-Jun-06 10:12 
Hey, I really like your article, the value of good Hello World examples is often underrated. I am, however having an issue with your use of csc in the post build step of some of the projects (namely the MCPP and the c# projects).
 
"csc /debug /t:module "$(OutDir)\$(ProjectName).dll""
 
Complains in Visual Studio .NET 2003 about the use of a binary file:
 
'Debug\HelloWorld.dll' is a binary file instead of a source code file
'Debug\HelloWorld.dll' could not be opened ('Unspecified error ')
 
I am by no means a .NET or even Visual Studio expert, but I can't seem to make this work.
 

 

 
http://www.kaireske.de/tvserien/fraggles/bilder/gorgs.jpg
 

-- modified at 17:14 Thursday 22nd June, 2006
AnswerRe: Other compiling problemsmemberdanmat28-Jun-06 21:31 
Try "csc /debug /t:module CSharpHelloWorld.cs"
 
that's the way I got this part working ..
QuestionCompiling Problemsmemberdanmat22-Jun-06 3:59 
I think I do understand the above technic, but I do not arrive to compile the c++ dll. Can anyone help me?
 
Thanks a lot
Daniela
GeneralObject-Oriented JNI (low-level) for DOTNET 1.0.03 ReleasedmemberVitaly Shelest25-Apr-06 0:57 
See this SDK at http://www.simtel.net/product.php[id]95126[sekid]0[SiteID]simtel.net[^],
it covers 90% of Standard JNI. You can write only managed JNI DOTNET code in C#, VB, C++ (Java native methods can be implemented only with managed DOTNET functions).;P
GeneralLoading managed dllsmemberjladd112-Apr-06 10:00 
Hi,
 
I am using this approach on one of my projects. Everything works as described. The first step is to make the C# class do some real work. When I add in a reference to a class in another managed dll, that dll is not loaded. The exception states "Could not load fileor assembly..."
 
Have you come across this exception when you are loading managed dlls via JNI?
 
Thanks,

 
Jim Ladd
GeneralRe: Loading managed dllsmemberRajesh Turlapati17-Nov-06 6:36 
I exactly have the same problem. Can you please let me know how you fixed it?
Thanks So much,
Rajesh
GeneralRe: Loading managed dllsmemberjladd120-Nov-06 10:34 
Hi,
 
I never achieved a solution. I had to change my approach (and code) to meet the project objectives.
 
If you discover the answer, please let me know.
 
Good luck,
Jim
GeneralRe: Loading managed dllsmemberRajesh Turlapati27-Nov-06 5:41 
Hi,
Thanks for the response. Right now I am trying a different approach by using Com Callable Wrapper(CCW) for the C# dll, but this gives a different native exception when JVM loads CCW. I am still working on it.
 
Thanks,
Rajesh

QuestionHow to pass a String parametermembermvmundlye12-Mar-06 19:43 
Can anyone help me with passing a String parameter to C# method from Java using the above technique?
AnswerRe: How to pass a String parametermemberrskousen23-Mar-06 12:29 
Try this link for some example code:
 
http://polelo.cs.up.ac.za/JavaCSharp_String_Passing.zip
 
I haven't actually tried it, but it seems like it would work. Wink | ;)
GeneralRe: How to pass a String parametermemberRacano23-May-07 4:51 
It's a broken link!
 
Claudio
GeneralRe: How to pass a String parametermemberchapsi26-Sep-07 10:46 
Yes its a broken link. Can someone forward the correct link ? I am having trouble in passing a String to the displayHelloWorld method. I have made the change to the method definition in both Java and C# and have created the corresponding .class, .h and .netmodule files. Now I need to make the change in the C++ part and create a new DLL (HelloWorld.dll). How do I do this ? How do I create a new C++ DLL ?
 

 
Thanks
Chapsi
GeneralGood work!memberSantosh K Sahoo22-Feb-06 2:50 
Good work on Interoperation, if you are looking to do something reverse, please have a look at IKVM.NET project on source forge[To call Java methods in .NET] Big Grin | :-D
 
Regards,
Santosh Ku Sahoo
GeneralWorks nicelymembertodd_stevenson17-Feb-06 4:57 

Used this method in a Research project I'm working on. The Company strongly wanted C# and Java for the windows client. There is more reason for this then one would think.
 

Good Job Smile | :)
Generalwhy...membertoxcct16-Feb-06 21:59 
why one would call a C# method (which is .NET targeted and mostly for Microsoft plateforms) from within a Java program (which is far more plateform independant than .NET) ????
 
moreover, installing both .NET framework and JVM/JRE takes a bit useless memory !!!

 

TOXCCT >>> GEII power
[toxcct][VisualCalc 2.24][3.0 soon...]
 
-- modified at 4:00 Friday 17th February, 2006
GeneralRe: why...memberKoriFrancis17-Feb-06 2:16 
Well, why not? Because of the nature of what I was doing at the time, I mostly wanted to see if it could be done. Yes I know it's quite strange that I'm making C# method calls from within Java, but .. I've never seen it done.
 
This doesn't necessarily need the .NET framework, as there is now the monoproject which brings .NET to most other *nix platforms. I haven't tested that yet, but I think I may just to see if it can be done.
 
The fact that the JVM/JRE and .Net framework take up useless memory (in your opinion) is moot to this article. As I've been saying, performance issues like that we're really in the scope of what I was doing.
 
Smile | :)
 
-- modified at 8:19 Friday 17th February, 2006
GeneralRe: why...memberAlfonso Villegas Jr.17-Feb-06 5:50 
If you had an application written in Java and the only way to solve a problem was through a C# library, then doing this would save lots of development time. Your question as to "why one would do this" can be answered with "whenever it would be a good solution to a problem". Believe me, there are definitely cases where I would see this solution be used.
AnswerRe: why...memberDoron Barak20-Feb-06 20:40 
Sometimes (rarely perhaps, but it happens), you need a certain sort of client behaviour on one platform, and another on another platform. Consider an application that requires a Web-enabled interface that is not simple HTML controls.
 
So you write your client as an Applet in Java, so it works on every platform with a JVM, but then, you're required to enable the same (or a part of) functionality under Microsoft Word for instance!!!
 
Yes, I actually had to write a system just like that, so from my experience I can say, these things do happen. My soloution did not involve C# (since C# was still in the idea phase, if not even sooner) but I had to integrate java code that worked as a service-providing-plugin for Microsoft Word and any other Microsoft application that the soloution was required to use.
 
The best way to accomplish my task was to use Visual J++ (a tool which has been replaced by J#, I believe) and wrap my Java Code as an ActiveX to be called from a VBA API.
 
VJ++ also provided the opposite function, i.e. calling Windows DLL code from within your Java classes, but this of course was wrapped by Microsoft classes that hid all the "dirty" code you have to write like loadLibrary and all that fun stuff Wink | ;)
 
About memory consumptions, again, please remember that both these systems are optimized and that the .NET framework is in fact a part of several sub-systems already running on Window OS's like XP anyway. Some people have it w/o even knowing its there or how it got there.
 
In any case, this is a highly theoretical situation but may happen, so when you need it, there's just no way around it. Smile | :)
GeneralRe: why...memberGeorge98765432121-Feb-06 6:32 
MONO[^] + IKVM[^] anyone?
 
Smile | :)
GeneralRe: why...memberAlfonso Villegas Jr.21-Feb-06 10:53 
How developed is IKVM? Is it as stable as .NET or the JVM? To be useful in an enterprise environment it would have to be more stable than the MONO project even. From what I read, it seems like it's still in some form of preliminary phase (alpha/beta).
GeneralRe: why...memberVitaly Shelest6-Jul-06 5:43 
See here why!Wink | ;)

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Permalink | Advertise | Privacy | Mobile
Web03 | 2.6.130617.1 | Last Updated 16 Feb 2006
Article Copyright 2006 by KoriFrancis
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid