Jon*_*erg 6 java arrays variables matlab pass-by-reference
考虑MyClass.java:
public class MyClass {
public void firstfunction(double fwd[]) {
fwd[0] = 42;
}
public void secondfunction(Double fwd[]) {
fwd[0] = new Double(42);
}
}
Run Code Online (Sandbox Code Playgroud)
这两个函数都返回值42 fwd
,对吗?
在MATLAB中,我想访问这个值42:
myobj=MyClass;
var1=0.0;
myobj.firstfunction(var1);
fprintf('%1.1f',var1); %// ... var1 is still 0.0 ... :-(
var2 = javaArray ('java.lang.Double',1);
var2(1)=java.lang.Double(0.0);
myobj.secondfunction(var2); %// var2 now contains the value 42 :-)
Run Code Online (Sandbox Code Playgroud)
虽然两个调用"工作"(原样:没有错误消息),但只有var2包含返回值42; var1仍然具有值0.0.
有没有办法使用MATLAB来调用函数firstfunction
并检索返回值?
一些背景知识: MATLAB可以在调用Java函数时传递Java对象,然后在MATLAB中可以对这些对象进行修改 - 除非 Java对象是原始数据类型的数组.在这种情况下,MATLAB和Java之间的自动转换开始,使得Java array-of-primitive-double直接对应于MATLAB中的双矩阵 - 这是通过MATLAB约定将事物"作为值传递",因此不可能返回值.所以我的问题可以改写,因为有什么方法可以解决这个问题吗?
(你可以在这里停止阅读.)
作为参考,我的特例是:
我有一个包含DLL 的Java类 MyClass.java,我想在MATLAB中使用它.但是,其中一个函数的返回值是double []作为参数传递,由于实现了与Java的交互,其内容不会返回到MATLAB.
有没有办法解决这个问题,而不修改DLL返回数据的方式?
这是丑陋的细节:
public class MyClass
{
static
{
System.load("C:\\fullpath\\mydll.dll");
}
public static native long SetFWD(double fwd);
public static native long GetFWD(double fwd[]);
}
Run Code Online (Sandbox Code Playgroud)
一旦我正确设置了javapath,这在MATLAB中就可以看到了:
>> methods MyClass -full
Methods for class MyClass:
static long GetFWD(double[])
MyClass()
static long SetFWD(double)
[and stuff inherited from java.lang.Object]
Run Code Online (Sandbox Code Playgroud)
我可以在MATLAB中调用函数SetFWD,但我不能让GetFWD返回任何东西:
myobj=MyClass;
fwd=3.0;
myobj.SetFWD(fwdval); % this works fine
fwd=0.0;
myobj.GetFWD(fwd); % this does not give an error, but fwd stays unmodified - as one would expect in MATLAB
fwd = javaArray ('java.lang.Double',1);
fwd(1) = java.lang.Double(0.0);
myobj.GetFWD(fwd) % this gives the error "??? No method 'GetFWD' with matching signature found for class 'MyClass'."
Run Code Online (Sandbox Code Playgroud)
从阅读MATLAB文档传递数据到Java方法和使用Java数组以及SO帖子从Java类型转移到MATLAB类型和从matlab传递到java的Strange类,我理解Matlab自动转换我传递给我的任何双数组将函数放入Java数组中,然后忽略这些数组中的任何修改.似乎如果MyClass中的函数定义包含Double对象而不是double原语,我的第二次尝试可能会起作用.
有没有办法让MATLAB返回我之后的值,而不修改原始的.DLL(mydll.dll)?
更新
我知道MATLAB通常会"按值"传递所有内容.但是在将数据传递给Java方法 Mathworks说
如果您需要访问的变化,一个Java方法,使一个数组,然后,而不是传递一个MATLAB阵列,您应该创建并通过Java数组,这是一个参考.
他们在使用Java Arrays时如何使用javaArray函数解释这一点,但是我无法使用它来创建数组double [](即原始双精度数组),仅用于Double [](即数组) Double对象)这不是我需要的,因为我的函数GetFWD()不吃后者:-(.
>> A=javaArray ('java.lang.double',1); % works fine, but cannot be used as parameter for my function GetFWD (see "No Method ... with matching signature..." error above)
>> A=javaArray ('double',1);
??? Error using ==> javaArray
No class double can be located on the MATLAB Java classpath
Run Code Online (Sandbox Code Playgroud)
不,它不能。
我找到了这个解决方法,我可以接受:虽然我无法(我自己)修改 DLL,但我可以在 java 类 MyClass 中添加一个包装函数,如下所示:
public static long GetFWDwrp(Double fwd[]) {
double tmp[]=new double[1];
long retval = MyClass.GetFWD(tmp);
fwd[0] = tmp[0];
return retval;
}
Run Code Online (Sandbox Code Playgroud)
这个包装函数有一个 Double 对象数组作为参数,我可以像这样从 MATLAB 访问它:
oldFW = javaArray ('java.lang.Double',1);
oldFW(1)=java.lang.Double(0.0);
myobj.GetFWDwrp(oldFW);
oldFW % this now contains the return value
Run Code Online (Sandbox Code Playgroud)
因此,这回答了我关于解决该问题的问题,因为它不涉及更改 DLL 的接口(仅涉及 Java 类的接口)。
然而,标题中更基本的问题仍然没有得到解答:在 MATLAB 中是否真的不可能将对 array-of-primitive-double 的引用传递给 Java 函数,从而绕过 Matlab-double-array 到 Java 的自动转换? Primitive-double-array 及其后面似乎使得无法访问 Java 代码对此类数组所做的任何更改。