Call C# method from Java using JNI


I've tried to follow the examples which I found here, but I am unable to get it to work. This is my Java class

package jniTester;
public class JNITester {
    static {

    public static native String welcome(String name);

From this I've created with javah the jniTester.h file

This is my C# class

namespace HelloWorldJNI

    public static class HelloWorldJNI
        public static String Welcome(String name)
            return "Hello " + name + "! This is your C# buddy.";

From this I've created HelloWorldJNI.netmodule

Here is my cpp class

#include "stdafx.h"
#include <jni.h>
#include <string>
#include "jniTester.h"
#using "D:\VisualStudio_C#_2017\SkriptumTeil5\HelloWorldJNI\HelloWorldJNI.netmodule"

using namespace std;

JNIEXPORT jstring JNICALL Java_jniTester_JNITester_welcome(JNIEnv *env, jclass thisclass, jstring inJNIStr) {
    // Step 1: Convert the JNI String (jstring) into C-String (char*)
    const char *inCStr = env->GetStringUTFChars(inJNIStr, NULL);
    if (NULL == inCStr) return NULL;

    // Step 2: Convert the C++ string to C-string, then to JNI String (jstring) and return
    //string outCppStr = "Hello " + std::string(inCStr) + ". Greetings from your C++ buddy";
    //env->ReleaseStringUTFChars(inJNIStr, inCStr);  // release resources
    //return env->NewStringUTF(outCppStr.c_str());

    //// Alternate Step 2:
    System::String^ outStr = HelloWorldJNI::HelloWorldJNI::Welcome(gcnew System::String(inCStr));
    env->ReleaseStringUTFChars(inJNIStr, inCStr);  // release resources
    char* converted = static_cast<char*>((System::Runtime::InteropServices::Marshal::StringToHGlobalAnsi(outStr)).ToPointer());
    return env->NewStringUTF(converted);

The code under Step 2 works. However this is not calling my C# method. The implementation under Alternate Step 2 fails with

# A fatal error has been detected by the Java Runtime Environment:
#  Internal Error (0xe0434352), pid=37224, tid=0x00003350

I am no cpp expert, so I am totally in the dark. What is wrong here?

asked on Stack Overflow May 15, 2018 by Walter Taus • edited May 15, 2018 by Walter Taus

1 Answer


First of all you need to create assembly DLL in C# with the COM interface.

Then you can make a native (unmanaged) DLL wrapper library, which you can use with JNI.

You can follow this guide for Calling Managed NET COM Objects from Unmanaged C code

Also you can check the JNI manual

And a short example:

The C# code Managed.cs

using System;
using System.Reflection;
using System.Runtime.InteropServices;

[assembly: ComVisible(true)] 
[assembly: AssemblyDelaySign(false)] 
[assembly: AssemblyVersion("")]
namespace ManagedClassLibrary {

    public interface IArithmetic {
        int sum(int lsh, int rhs);
        int subtract(int lsh, int rhs);
    public class ArithmeticImpl:IArithmetic {

        public int sum(int lsh, int rhs)
             return lsh + rhs;
        public int subtract(int lsh, int rhs)
             return lsh - rhs;


The C++ dll wrapper code dotnet_arithmetic.cpp

#include <windows.h>
#include <Objbase.h>

#include <jni.h>

#import "Managed.tlb" named_guids raw_interfaces_only

using namespace Managed;

class DNArithmetic 
    DNArithmetic(const DNArithmetic&) = delete;
    DNArithmetic& operator=(const DNArithmetic&) = delete;
    DNArithmetic() noexcept
    const DNArithmetic* instanse() {
        if(!_co_init) { 
         _co_init = true;
        static DNArithmetic _ret;            
        return &_ret;
    int sum(int lsh, int rhs) const {
        int ret;
        mi_->sum(lsh, rhs, &ret);
        return ret;

    int subtract(int lsh, int rhs) const {
        int ret;
        mi_->subtract(lsh, rhs, &ret);
        return ret;

    ~DNArithmetic() noexcept
    IArithmeticPtr mi_;
    static bool _co_init;

bool DNArithmetic::_co_init = false;

extern "C" {

    JNIEXPORT jint JNICALL Java_Arithmetic_dotnet_1sum(JNIEnv *evn, jclass clazz, jint lsh, jint rhs)
        return DNArithmetic::instance()->sum(lsh, rhs);

    JNIEXPORT jint JNICALL Java_Arithmetic_dotnet_1subtract(JNIEnv *evn, jclass clazz, jint lsh, jint rhs)
        return DNArithmetic::instance()->subtract(lsh, rhs);

    BOOL WINAPI DllMain(::HMODULE hprocess,::DWORD fdwReason,::LPVOID lpvReserved)
        switch (fdwReason) {
        case DLL_PROCESS_ATTACH:           
        case DLL_PROCESS_DETACH:                
        case DLL_THREAD_ATTACH:
        case DLL_THREAD_DETACH:
        return TRUE; // successful


The Java Code

public class Arithmetic {

    private static native int dotnet_sum(int lsh, int rhs);

    private static native int dotnet_subtract(int lsh, int rhs);

    private Arithmetic() {
        try {
        } catch (UnsatisfiedLinkError e) {
            throw new IllegalStateException(e);

    private int sum(int lsh, int rhs) {
        return  dotnet_sum(lsh, rhs);

    private int subtract(int lsh, int rhs) {
        return dotnet_subtract(lsh,rhs);

    public static void main(String[] args) {
        System.setProperty("java.library.path", System.getProperty("user.dir") );
        System.out.println("About to call C# functions from Java over the MS COM");
        Arithmetic instance = new Arithmetic();
        System.out.println("C# 1 + 2 = " + instance.sum(1,2) );
        System.out.println("C# 2 - 1 = " + instance.subtract(2,1) );

And a build file build.cmd (simple bat file for demo proposes)

@echo off
rem make sure you have JAVA_HOME system variable set
rem Please set your VS root dir, should be  somewhere in C:\Program Files 
echo %VS_HOME%

echo Take Visual studio command line tools
    call %VS_HOME%\VC\Auxiliary\Build\vcvars64.bat

echo Build C# class library
    sn /k Managed.snk
    csc /optimize /target:library /out:Managed.DLL Managed.cs
    RegAsm  Managed.DLL /tlb:Managed.tlb
    gacutil /i Managed.DLL 

echo Build C++ wrapper JNI DLL
    cl /c /nologo /GL /Zl /std:c++latest /I%JAVA_HOME%\include /I%JAVA_HOME%\include\win32 /Fodotnet_arithmetic.obj dotnet_arithmetic.cpp
    link /DLL /LTCG /LIBPATH:%JAVA_HOME%\lib /OUT:dotnet_arithmetic.dll msvcrt.lib kernel32.lib Ole32.lib jvm.lib dotnet_arithmetic.obj

echo Build Java


echo Running the Demo

java Arithmetic


NOTE: This solution for Windows OS only. And should not work for Mono on Unix.

answered on Stack Overflow May 16, 2018 by Victor Gubin • edited May 21, 2018 by Victor Gubin

User contributions licensed under CC BY-SA 3.0