I've created a c# dll in visual studio 2008
the content of the c# dll is as given below:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace hello
{
public class Class1
{
public static double addUp(double number, double Number)
{
return number + Number;
}
public static double minus(double number, double Number)
{
return number - Number;
}
}
}
and through java i've loaded the hello.dll using
System.loadLibrary("hello");
The java code is as given below:
package pkgnew;
import javax.swing.JOptionPane;
public class check
{
public static native double addUp(double number,double Number);
static
{
try
{
System.loadLibrary("hello");
System.out.println("SUCCESS");
}catch(Exception ex){ JOptionPane.showMessageDialog(null,"Required DLLs Not Found\n"+ex.getCause(),"Error Loading Libraries", JOptionPane.ERROR_MESSAGE);}
}
public static void main(String[] args)
{
new check().getval();
}
public void getval() {
try
{
double g=this.addUp(52.2, 51.3);
}catch(Exception y){System.out.println("ERROR IS:"+y);}
}
}
but the problem is that i'm getting output as:
OUTPUT
SUCCESS
Exception in thread "main" java.lang.UnsatisfiedLinkError: pkgnew.check.addUp(DD)D
at pkgnew.check.addUp(Native Method)
at pkgnew.check.getval(check.java:35)
at pkgnew.check.main(check.java:29)
Java Result: 1
Can anyone tell me why i'm getting this error....and why i'm not able to call the dll methods
I don't think you can call native extensions in Java without using JNI wrappers (or at least some library which translates to JNI under the hood). Have you tried out the frameworks/suggestions mentioned in this thread?
You cannot directly call C# dll in Java. There is a workaround. You'll have to first write a C++ managed class for C# code then create a of C++ dll and use it in java.
This link might be helpful.
Related
I'm writing an application that uses the LuaJ library to load and interpret Lua code. I have the following code which is an OneArgFunction.
static class addCommand extends OneArgFunction {
public LuaValue call(LuaValue x) {
if(x.isfunction()) {
LuaClosure closure = x.checkclosure();
closure.call();
return LuaValue.valueOf(true);
} else {
return LuaValue.valueOf(false);
}
}
}
What I need is to convert the LuaClosure to a Java method and invoke it. How could I do this?
Sorry if this question is hard to understand, as I'm not good at English.
I'm controlling some external device using my android app, and in order to control this device it provides an sdk which is a C#(.dll) files, I know how to load .dll libraries into java and how to use it, but I can't access a lot of methods inside these libraries because it takes C# native arguments like structs which is not available in Java, and I tried equivalents in Java like classes with public elements to represent a struct but it keeps give me the error: java.lang.IllegalArgumentException: Unsupported argument type
This is how I deal with the Library(using jna):
import outsource.classes.MyClass;
import com.sun.jna.Library;
import com.sun.jna.Native;
public class Test {
public interface simpleDLL extends Library {
long H264_DVR_GetLastError(int num); // accessed without any problems
boolean H264_DVR_SetDVRMessCallBack(MyClass obj, long num); // this "MyClass" is mainly a STRUCT in the C# sdk
}
static
{
System.loadLibrary("NetSdk");
}
public static void main(String args[]) {
simpleDLL INSTANCE = (simpleDLL) Native.loadLibrary(("NetSdk"),
simpleDLL.class);
System.out.println(INSTANCE.H264_DVR_GetLastError(4));
System.out.println(INSTANCE.H264_DVR_SetDVRMessCallBack(new MyClass(),
0));
}
}
And this is how I created MyClass.Class:
public class MyClass() {
public String Id = "myDevice";
public String UserName = "admin";
public int password = 1234;
}// also tried declaring the values inside a constructor but nothing changed
and this is how the struct defined inside the sdk:
typedef struct _DEVICEINFO
{
char id[64];
char user[64];
int pw;
}DEVICEINFO,*LP_DEVICEINFO;
p.s. I know there are some ways to write an android app with C# code using VisualBasic(e.g vs-android) but that won't work in my case as the app is already written and running with java and it's pretty huge with a lot of other functionalists so it can't be rewritten.
I have one c++ dll file. And I know the methods used in it. I need to call these methods from my java code. I don't have access to modify the DLL file. Please provide me a solution to do this.
I created JavaCPP exactly for that purpose. I'll copy/paste some sample code and explanations from the page:
The most common use case involves accessing some legacy library written for C++, for example, inside a file named LegacyLibrary.h containing this C++ class:
#include <string>
namespace LegacyLibrary {
class LegacyClass {
public:
const std::string& get_property() { return property; }
void set_property(const std::string& property) { this->property = property; }
std::string property;
};
}
To get the job done with JavaCPP, we can easily define a Java class such as this one--although one could use the Parser to produce it from the header file as demonstrated below:
import com.googlecode.javacpp.*;
import com.googlecode.javacpp.annotation.*;
#Platform(include="LegacyLibrary.h")
#Namespace("LegacyLibrary")
public class LegacyLibrary {
public static class LegacyClass extends Pointer {
static { Loader.load(); }
public LegacyClass() { allocate(); }
private native void allocate();
// to call the getter and setter functions
public native #StdString String get_property(); public native void set_property(String property);
// to access the member variable directly
public native #StdString String property(); public native void property(String property);
}
public static void main(String[] args) {
// Pointer objects allocated in Java get deallocated once they become unreachable,
// but C++ destructors can still be called in a timely fashion with Pointer.deallocate()
LegacyClass l = new LegacyClass();
l.set_property("Hello World!");
System.out.println(l.property());
}
}
Alternately, we can produce a Java interface by parsing the header file with a config class such as this one:
#Properties(target="LegacyLibrary", value=#Platform(include="LegacyLibrary.h"))
public class LegacyLibraryConfig implements Parser.InfoMapper {
public void map(Parser.InfoMap infoMap) {
}
}
And the following build commands:
$ javac -cp javacpp.jar LegacyLibraryConfig.java
$ java -jar javacpp.jar LegacyLibraryConfig
$ javac -cp javacpp.jar LegacyLibrary.java
$ java -jar javacpp.jar LegacyLibrary
For more complex examples including Maven/IDE integration, check out the JavaCPP Presets!
I am trying to generate a dll which I can access from java via JNA.
I just try a simple one:
CPP:
void Initialize()
{
std::cout<< "Hello World!";
}
iostream is also included and after compiling I get: CreateDll.dll
Via Visual Studio I can generate now a *.dll.
which I try loading into Java like:
public class mainRoutine {
public static void main(String[] args) {
NativeWrapper INSTANCE = (NativeWrapper) Native.loadLibrary("CreateDll" , NativeWrapper.class);
INSTANCE.Initialize();
}
static {
System.setProperty("jna.library.path", "C:\\workspace\\JNA");
}
}
There is also another Interface:
import com.sun.jna.Library;
public interface NativeWrapper extends Library {
void Initialize();
}
So but now running the Java function I get the error,
java.lang.UnsatisfiedLinkError:
Error looking up function 'Initialize':
The specified procedure could not be found.
What am I missing?
PS: I know there are many topics, but trying for a day already I have not found the solution. Please help me.
You need to both export and (if using C++) un-decorate the function name.
On windows, functions are typically made available for export with __declspec(dllexport).
On any platform, to ensure a function is exported in unmanagled form, you must use extern "C".
Specifically:
extern "C" void __declspec(dllexport) Initialize() { ... }
There are other ways to designate exported functions, but this is probably the most common and straightforward to use. If you don't use extern "C", your function will look something like InitializeZ#ASDF#, where the additional garbage characters are used by the compiler and linker to make a given function uniquely recognizable based on its calling signature.
Are you exporting the symbol:
void _declspec(dllexport) Initialize()
{
std::cout<< "Hello World!";
}
What if there is a class to be implemented ? where the .h file looks like this:
namespace simpleDLLNS
{
class simpleDLL
{
public:
char giveVoidPtrGetChar(void* param);
int giveIntGetInt(int a);
void simpleCall(void);
int giveVoidPtrGetInt(void* param);
};
}
Where should extern "C" void __declspec(dllexport) be used ?
I used it when implementing the functions. but when i opened the dll, it looked like this:
?simpleCall#simpleDLL#simpleDLLNS##QAEXXZ
I compiled following JavaScript file, "test.js", into the "test.class" :
var test = (function () {
var that = {};
that.addNumbers = function (a, b) {
return a+b;
};
return that;
}());
I would like to call the compiled JavaScript function, "test.addNumbers(1,2)", in the simple Java program "run.java" as follows :
public class run {
public static void main(String[] args) throws Exception {
Context cx = Context.enter();
try {
Scriptable scope = cx.initStandardObjects();
// HOW TO CALL THE METHOD, Test.addNumbers(1,2)? Please help me!
} finally {
Context.exit();
}
}
}
I tried many ways, but failed. I read Rhino tutorial and examined many articles and examples, BUT they only show how to call JavaScript methods from the command line or the source file, "test.js".
I need to call the method from the compiled "test.class" file.
Thanks much in advance for your help!
Using javap, I believe that the JavaScript type test does not mean that the resultant Java type is this class. The generated Java type invokes the script code in its constructor; this will not result in exposing addNumbers as a Java method.
>javap -classpath . test
public class test extends org.mozilla.javascript.NativeFunction implements org.m
ozilla.javascript.Script{
public test(org.mozilla.javascript.Scriptable, org.mozilla.javascript.Contex
t, int);
public test();
public static void main(java.lang.String[]);
public final java.lang.Object exec(org.mozilla.javascript.Context, org.mozil
la.javascript.Scriptable);
public final java.lang.Object call(org.mozilla.javascript.Context, org.mozil
la.javascript.Scriptable, org.mozilla.javascript.Scriptable, java.lang.Object[])
;
public int getLanguageVersion();
public java.lang.String getFunctionName();
public int getParamCount();
public int getParamAndVarCount();
public java.lang.String getParamOrVarName(int);
public java.lang.String getEncodedSource();
public boolean getParamOrVarConst(int);
}
Reading between the lines, I'd say you need to map to Java types to do what you want. From the jsc doc:
-implements java-intf-name
Specifies that a java class
implementing the Java interface
java-intf-name should be generated
from the incoming JavaScript source
file. Each global function in the
source file is made a method of the
generated class, implementing any
methods in the interface by the same
name.
Define this interface:
//Adder.java
public interface Adder {
public int addNumbers(int a, int b);
}
Write this implementation:
//AdderImpl.js
function addNumbers(a, b) {
return a+b;
}
Compile the JavaScript with the arguments -implements Adder AdderImpl.js. Invoke the method like so:
Adder adder = new AdderImpl();
int n = adder.addNumbers(1, 2);
System.out.println(n);
I'd hazard a guess that it was probably necessary to do it this way because of differences in the languages' type systems.
I used Rhino 1.7R2. For the sake of brevity, I've avoided using packages, etc.