草庐IT

java - MATLAB 不能从 Java 读回 double[] 数组吗?

coder 2024-04-02 原文

考虑 MyClass.java:

public class MyClass {
  public void firstfunction(double fwd[]) {
   fwd[0] = 42;
  }
  public void secondfunction(Double fwd[]) {
   fwd[0] = new Double(42);
  }
}

这两个函数都在 fwd 中返回值 42,对吗?

我想从 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  :-)

虽然都调用了“work”(原样:没有错误消息),但只有 var2 包含返回值 42; var1 的值仍然是 0.0。

有什么方法可以使用 MATLAB 调用函数 firstfunction 并检索返回值?


一些背景:MATLAB 可以在调用 Java 函数时传递 Java 对象,并且随后可以在 MATLAB 中对这些对象进行修改 - except 当 Java 对象是数组时原始数据类型。在这种情况下,MATLAB 和 Java 之间的自动转换启动,使 Java 基本 double 组直接对应于 MATLAB 中的 double 矩阵——根据 MA​​TLAB 约定,这是“作为值传递”的东西,因此不可能有返回值。所以我的问题可以改写为有什么办法解决这个问题吗?


(你可以在这里停止阅读。)

作为引用,我的特例是这样的:

我有一个 Java 类 MyClass.java 包装了一个 DLL,我想在 MATLAB 中使用它。但是,其中一个函数的返回值是作为参数传递的double[],由于交互方式,其内容不会返回 MATLAB用 Java 实现。

有没有办法解决这个问题,而不修改 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[]);
}

一旦我正确设置了 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]

我可以从 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'."

来自阅读 MATLAB 文档 Passing Data to a Java MethodWorking with Java Arrays以及 SO 帖子 Moving from Java types back to MATLAB typesStrange classes passed from matlab to java ,我知道 Matlab 会自动将我传递给函数的任何 double 组转换为 Java 数组,然后忽略对这些数组所做的任何修改。似乎如果我在 MyClass 中的函数定义包含 Double 对象而不是 double 基元,我的第二次尝试就可以成功。

有没有办法让 MATLAB 返回我想要的值,而不修改原始 .DLL (mydll.dll)?

更新

我知道 MATLAB 通常“按值”传递所有内容。但是在Passing Data to a Java Method Mathworks 是这么说的

If you need to access changes that a Java method makes to an array, then, rather than passing a MATLAB array, you should create and pass a Java array, which is a reference.

他们在 Working with Java Arrays 中解释如何使用 javaArray 函数做到这一点,但我无法让它用于创建数组 double[](即原始 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

最佳答案

不,它不能。

我找到了这个解决方法,我可以接受:虽然我不能(我自己)修改 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;
}

这个包装函数有一个 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

所以这回答了我关于问题的解决方法的问题,因为它不涉及更改 DLL 的接口(interface)(仅 Java 类的接口(interface))。

然而,标题中更基本的问题仍未得到解答:在 MATLAB 中是否真的不可能将对 array-of-primitive-double 的引用传递给 Java 函数,绕过自动将 Matlab-double-array 转换为 Java-primitive-double-array 并返回,这似乎使得无法访问 Java 代码对此类数组所做的任何更改。

关于java - MATLAB 不能从 Java 读回 double[] 数组吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5554518/

有关java - MATLAB 不能从 Java 读回 double[] 数组吗?的更多相关文章

  1. ruby-on-rails - 在 Ruby 中循环遍历多个数组 - 2

    我有多个ActiveRecord子类Item的实例数组,我需要根据最早的事件循环打印。在这种情况下,我需要打印付款和维护日期,如下所示:ItemAmaintenancerequiredin5daysItemBpaymentrequiredin6daysItemApaymentrequiredin7daysItemBmaintenancerequiredin8days我目前有两个查询,用于查找maintenance和payment项目(非排他性查询),并输出如下内容:paymentrequiredin...maintenancerequiredin...有什么方法可以改善上述(丑陋的)代

  2. ruby - 多次弹出/移动 ruby​​ 数组 - 2

    我的代码目前看起来像这样numbers=[1,2,3,4,5]defpop_threepop=[]3.times{pop有没有办法在一行中完成pop_three方法中的内容?我基本上想做类似numbers.slice(0,3)的事情,但要删除切片中的数组项。嗯...嗯,我想我刚刚意识到我可以试试slice! 最佳答案 是numbers.pop(3)或者numbers.shift(3)如果你想要另一边。 关于ruby-多次弹出/移动ruby​​数组,我们在StackOverflow上找到一

  3. ruby - 将数组的内容转换为 int - 2

    我需要读入一个包含数字列表的文件。此代码读取文件并将其放入二维数组中。现在我需要获取数组中所有数字的平均值,但我需要将数组的内容更改为int。有什么想法可以将to_i方法放在哪里吗?ClassTerraindefinitializefile_name@input=IO.readlines(file_name)#readinfile@size=@input[0].to_i@land=[@size]x=1whilex 最佳答案 只需将数组映射为整数:@land边注如果你想得到一条线的平均值,你可以这样做:values=@input[x]

  4. ruby - 通过 erb 模板输出 ruby​​ 数组 - 2

    我正在使用puppet为ruby​​程序提供一组常量。我需要提供一组主机名,我的程序将对其进行迭代。在我之前使用的bash脚本中,我只是将它作为一个puppet变量hosts=>"host1,host2"我将其提供给bash脚本作为HOSTS=显然这对ruby​​不太适用——我需要它的格式hosts=["host1","host2"]自从phosts和putsmy_array.inspect提供输出["host1","host2"]我希望使用其中之一。不幸的是,我终其一生都无法弄清楚如何让它发挥作用。我尝试了以下各项:我发现某处他们指出我需要在函数调用前放置“function_”……这

  5. ruby - 检查数组是否在增加 - 2

    这个问题在这里已经有了答案:Checktoseeifanarrayisalreadysorted?(8个答案)关闭9年前。我只是想知道是否有办法检查数组是否在增加?这是我的解决方案,但我正在寻找更漂亮的方法:n=-1@arr.flatten.each{|e|returnfalseife

  6. java - 等价于 Java 中的 Ruby Hash - 2

    我真的很习惯使用Ruby编写以下代码:my_hash={}my_hash['test']=1Java中对应的数据结构是什么? 最佳答案 HashMapmap=newHashMap();map.put("test",1);我假设? 关于java-等价于Java中的RubyHash,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/22737685/

  7. ruby - 如果指定键的值在数组中相同,如何合并哈希 - 2

    我有一个这样的哈希数组:[{:foo=>2,:date=>Sat,01Sep2014},{:foo2=>2,:date=>Sat,02Sep2014},{:foo3=>3,:date=>Sat,01Sep2014},{:foo4=>4,:date=>Sat,03Sep2014},{:foo5=>5,:date=>Sat,02Sep2014}]如果:date相同,我想合并哈希值。我对上面数组的期望是:[{:foo=>2,:foo3=>3,:date=>Sat,01Sep2014},{:foo2=>2,:foo5=>5:date=>Sat,02Sep2014},{:foo4=>4,:dat

  8. ruby - 在 Ruby 中用键盘诅咒数组浏览 - 2

    我正在尝试在Ruby中制作一个cli应用程序,它接受一个给定的数组,然后将其显示为一个列表,我可以使用箭头键浏览它。我觉得我已经在Ruby中看到一个库已经这样做了,但我记不起它的名字了。我正在尝试对soundcloud2000中的代码进行逆向工程做类似的事情,但他的代码与SoundcloudAPI的使用紧密耦合。我知道cursesgem,我正在考虑更抽象的东西。广告有没有人见过可以做到这一点的库或一些概念证明的Ruby代码可以做到这一点? 最佳答案 我不知道这是否是您正在寻找的,但也许您可以使用我的想法。由于我没有关于您要完成的工作

  9. ruby - 如何在 Grape 中定义哈希数组? - 2

    我使用Ember作为我的前端和GrapeAPI来为我的API提供服务。前端发送类似:{"service"=>{"name"=>"Name","duration"=>"30","user"=>nil,"organization"=>"org","category"=>nil,"description"=>"description","disabled"=>true,"color"=>nil,"availabilities"=>[{"day"=>"Saturday","enabled"=>false,"timeSlots"=>[{"startAt"=>"09:00AM","endAt"=>

  10. java - 从 JRuby 调用 Java 类的问题 - 2

    我正在尝试使用boilerpipe来自JRuby。我看过guide从JRuby调用Java,并成功地将它与另一个Java包一起使用,但无法弄清楚为什么同样的东西不能用于boilerpipe。我正在尝试基本上从JRuby中执行与此Java等效的操作:URLurl=newURL("http://www.example.com/some-location/index.html");Stringtext=ArticleExtractor.INSTANCE.getText(url);在JRuby中试过这个:require'java'url=java.net.URL.new("http://www

随机推荐