Calling C# method within a Java program
Asked Answered
M

2

15

C# methods cannot be called directly in Java using JNI due to different reasons. So first we have to write a wrapper for C# using C++ then create the dll and use it through JNI in Java.

I have problem in calling C# code in C++. I'm adding C# .netmodule file to a C++ project. Code is pasted below. Please guide me if i'm doing anything wrong.

This is my managed C++ class UsbSerialNum.h:

#using <mscorlib.dll>
#include <iostream>
#using "UsbSerialNumberCSharp.netmodule"

using namespace std;

using namespace System;

public __gc class UsbSerialNum
{
    public:

        UsbSerialNumberCSharp::UsbSerialNumberCSharp __gc *t;

        UsbSerialNum() {
            cout<<"Hello from C++";
            t = new UsbSerialNumberCSharp::UsbSerialNumberCSharp();
        }

        void CallUsbSerialNumberCSharpHello() {
            t->hello();
        }
};

C# UsbSerialNumberCSharp.cs file from which i've created the .netmodule file:

using System.Collections.Generic;
using System.Text;

namespace UsbSerialNumberCSharp
{
    public class UsbSerialNumberCSharp
    {

        public UsbSerialNumberCSharp(){
            Console.WriteLine("hello");
        }

        public static void hello()
        {
            Console.WriteLine("hello");
        }

        public void helloCSharp ()
        {
            Console.WriteLine("helloCSharp");
        }
    }
}

Here is my main makeDLL.cpp file from which makeDLL.dll is created:

#include "jni.h"
#include <iostream>


// This is the java header created using the javah -jni command.
#include "testDLL.h"


// This is the Managed C++ header that contains the call to the C#
#include "UsbSerialNum.h"

using namespace std;


JNIEXPORT void JNICALL Java_testDLL_hello
(JNIEnv *, jobject) {

    // Instantiate the MC++ class.
    UsbSerialNum* serial = new UsbSerialNum();
    serial->CallUsbSerialNumberCSharpHello();
}

Here is my java class:

public class testDLL {

    static {
        System.loadLibrary("makeDLL");
    }

    /**
     * @param args
     */
    public static void main (String[] args) {
        //        new testDLL().GetUSBDevices("SCR3", 100);
        new testDLL().hello();
    }

    public native void hello();

}

EDIT:

If i simply ignore the call to UsbSerial.h in my main file i.e. use simple C++ then my code is working fine in Java. Basically C++ managed class is not working properly. Please guide me. Thanks.

Munos answered 18/11, 2011 at 11:1 Comment(14)
at which point you are getting the error?Poeticize
What's the problem? Is this managed C++? I don't recognize the __gc bitsWritein
i've edited the question. please check it out. thanks.Munos
@BumbleBee: when pointer of UsbSerial serial* is created and constructor is called. That is where i'm getting the error.Munos
@flipchart: __gc is used to make a garbage collectable instance to be compatible with java...Munos
If this is for Java, then the c# tag is wrongWritein
@flipchart: actually problem is with the C#, C++ classes not with java. (i guess)Munos
Why don't you import the C++ classes instead of getting what basically amounts to twice the work. Just convert your C# dll to java...Hansel
@Ramhound: Can't use C# dll directly in java. It does not work...Munos
@Justin: Error message is displayed when i call the function in java. It is some kind of excess violation...Munos
Access violation is about as a generic error as you can get in C++ world. "__gc is used to make a garbage collectable instance to be compatible with java" - this part does not make sense: you cannot have the Java GC manage anything outside of the Java VM, so it's probably going to make more harm than good.Catamount
Can you please elaborate a bit more?... Which API are you trying to use?Quartile
@UmerHayat: What i want actually is to get the serial number of connected usb device and for this i'm querying WMI in C# and trying to use it in Java through JNI..Munos
@UmerHayat: There is no specific API in C#. I'm using some built-in namespace System.Management..Munos
C
8

It would be useful to know what you need this interoperability for exactly. In any case, you should look into IKVM; alternatively you can (as has been suggested for a similar problem) use COM as a bridge: expose the C#/CLR as a COM interface and then use com4j in Java.

Catamount answered 18/11, 2011 at 15:8 Comment(1)
I want to get the serial number of all attached USBs, have already written the code in C#, want to use it in Java.Munos
Q
0

You can avoid C# and still can query WMI using C++ only. See Using WMI to call method on objects

Quartile answered 28/11, 2011 at 5:34 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.