返回信息流c代码
_declspec(dllexport)struct coord_xy convert_bl_to_xy(struct coord_bl *coord_bl);
struct coord_bl {
int type;
double lon, lat;
};
struct coord_xy {
int type;
double x, y;
};
生成dll 然后java调用,下边java 代码
public interface TestDLL extends Library{
TestDLL INSTANCE = (TestDLL) Native
.loadLibrary((Platform.isWindows() ? "XXXX" : "c"),
TestDLL.class);
public Coord_xy convert_bl_to_xy(Coord_bl.ByReference coord_bl);
public static class Coord_bl extends Structure {
public static class ByReference extends Coord_bl implements Structure.ByReference{}
public static class ByValue extends Coord_bl implements Structure.ByValue{}
public int type;
public double lon, lat;
}
public static class Coord_xy extends Structure {
public static class ByReference extends Coord_xy implements Structure.ByReference{}
public static class ByValue extends Coord_xy implements Structure.ByValue{}
int type;
double x, y;
}
}
public static void main(String[] args) {
Coord_bl.ByReference bl = new Coord_bl.ByReference();
bl.type = Macro.COORD_BL;
bl.lat = 39.26;
bl.lon = 115.25;
Coord_xy xy = TestDLL.INSTANCE.convert_bl_to_xy(bl);
}
囧 每次都会报异常,跪求帮助。。。。
Exception in thread "main" java.lang.UnsatisfiedLinkError: Error looking up function 'convert_bl_to_xy': O?>>u 1/2 ?¨u
at com.sun.jna.Function.<init>(Function.java:179)
at com.sun.jna.NativeLibrary.getFunction(NativeLibrary.java:345)
at com.sun.jna.NativeLibrary.getFunction(NativeLibrary.java:325)
at com.sun.jna.Library$Handler.invoke(Library.java:203)
at $Proxy0.convert_bl_to_xy(Unknown Source)
at etestJNA.JNAExtractorInterface.main(JNAExtractorInterface.java:42)
这是一条镜像帖。来源:北邮人论坛 / java / #40088同步于 2015/4/22
该镜像源已超过 30 天没有更新,可能在源站已被删除。
Java机器人发帖
关于JNA调用dll的问题
wbzj1110
2015/4/22镜像同步10 回复
订阅后,新回复会通过你的通知中心匿名送达。
9 条回复
额。。dll已经放到 当前工作目录。。。test的时候调用了一个简单的dll的show阔以调用到 应该不是找不到dll的原因哈,找不到dll会报load不进去 而不是UnsatisfiedLinkError
loadLibrary((Platform.isWindows() ? "XXXX" : "c")
这一行应该是JNA的例子上的代码吧。这段代码要把库名改成你的dll的路径。
是不是用C++编译器编译的呢?会进行name mangling的。如果是的话,要 extern "C"
表示一开始想太多了。。没必要这么麻烦。。。其实本身是不想用c/c++的囧 被逼迫的 所以就换了一个思路 http://blog.csdn.net/wbzj1110/article/details/45557105
另:感谢暖羊羊大神回复。。。
【 在 nuanyangyang 的大作中提到: 】
: loadLibrary((Platform.isWindows() ? "XXXX" : "c")
: 这一行应该是JNA的例子上的代码吧。这段代码要把库名改成你的dll的路径。
: 是不是用C++编译器编译的呢?会进行name mangling的。如果是的话,要 extern "C"
我这里有一个可以跑的版本。
我用的是JNA 4.2.0,不知你用的是哪个版本。
C代码 coord.c:我不会经纬度变换,就改成极坐标转直角坐标了。
#include <math.h>
struct coord_polar {
int type;
double mag, ang;
};
struct coord_xy {
int type;
double x, y;
};
struct coord_xy convert_polar_to_xy(struct coord_polar *coord_polar) {
struct coord_xy result;
result.type = 42;
result.x = coord_polar->mag * cos(coord_polar->ang);
result.y = coord_polar->mag * sin(coord_polar->ang);
return result;
}
编译(linux):gcc -fPIC -shared -lm -o libcoord.so boord.c
生成的libcoord.so放在工作目录下的一个叫c的目录里。
Java代码:
package cn.byr.nuanyangyang.coord;
import java.util.Arrays;
import java.util.List;
import cn.byr.nuanyangyang.coord.CoordJNATest.TestDLL.Coord_polar;
import cn.byr.nuanyangyang.coord.CoordJNATest.TestDLL.Coord_xy;
import com.sun.jna.Library;
import com.sun.jna.Native;
import com.sun.jna.Structure;
public class CoordJNATest {
public interface TestDLL extends Library {
TestDLL INSTANCE = (TestDLL) Native.loadLibrary("./c/libcoord.so",
TestDLL.class);
// 留意返回值的ByValue。如果不是ByValue,默认是认为返回struct指针的。
//
// 官方文档如此叙述:https://github.com/java-native-access/jna/blob/master/www/StructuresAndUnions.md
// When a function requires a pointer to a struct, a Java Structure
// should be used. If the struct is passed or returned by value, you
// need only make minor modifications to the parameter or return type
// class declaration.
//
// 而Structure类的JavaDoc如是说:
// Represents a native structure with a Java peer class. When used as a
// function parameter or return value, this class corresponds to
// struct*. When used as a field within another Structure, it
// corresponds to struct. The tagging interfaces ByReference and ByValue
// may be used to alter the default behavior. Structures may have
// variable size, but only by providing an array field (e.g. byte[]).
public Coord_xy.ByValue convert_polar_to_xy(
Coord_polar.ByReference coord_polar);
public static class Coord_polar extends Structure {
public static class ByReference extends Coord_polar implements
Structure.ByReference {
}
public static class ByValue extends Coord_polar implements
Structure.ByValue {
}
public int type;
public double mag, ang;
// 这个方法要覆盖的。
@Override
protected List<String> getFieldOrder() {
return Arrays.asList("type", "mag", "ang");
}
}
public static class Coord_xy extends Structure {
public static class ByReference extends Coord_xy implements
Structure.ByReference {
}
public static class ByValue extends Coord_xy implements
Structure.ByValue {
}
public int type;
public double x, y;
@Override
protected List<String> getFieldOrder() {
return Arrays.asList("type", "x", "y");
}
}
}
public static void main(String[] args) {
Coord_polar.ByReference bl = new Coord_polar.ByReference();
bl.type = 30;
bl.mag = 2.0;
bl.ang = Math.PI / 6.0;
Coord_xy xy = TestDLL.INSTANCE.convert_polar_to_xy(bl);
System.out.format("%d %f %f\n", xy.type, xy.x, xy.y);
}
}
输出:
42 1.732051 1.000000
看样子问题就是Structure作为参数和返回值的时候默认是ByReference而不是ByValue的。确实,把Struct当值传入和传出是很麻烦的,读ABI都能把人读得欲仙欲死,而且Windows和Linux不一样。
是滴来 所以简单但是性能不知道是否有损失的方法,就是直接返回char* 也就是java的String就好啦。。——!
【 在 nuanyangyang 的大作中提到: 】
: 我这里有一个可以跑的版本。
: 我用的是JNA 4.2.0,不知你用的是哪个版本。
: C代码 coord.c:我不会经纬度变换,就改成极坐标转直角坐标了。
: ...................
感谢~~暖羊羊大神~~[ema3]
【 在 nuanyangyang 的大作中提到: 】
: 我这里有一个可以跑的版本。
: 我用的是JNA 4.2.0,不知你用的是哪个版本。
: C代码 coord.c:我不会经纬度变换,就改成极坐标转直角坐标了。
: ...................
【 在 wbzj1110 的大作中提到: 】
: 是滴来 所以简单但是性能不知道是否有损失的方法,就是直接返回char* 也就是java的String就好啦。。——!
对了,今天中午开会,一个老师痛斥C语言的“允许按值返回struct”这个特性,他告诉我compcert C编译器(一个验证过的C编译器)对struct返回值的处理和别的C编译器(当然以及平台ABI)有所区别,总之比较麻烦。看来人们都不喜欢C语言这个特性。
虽然明白细节。。但是大概意思就是不太推荐使用这个吧。。。[ema1]太高端了。。有点听不懂。。
【 在 nuanyangyang 的大作中提到: 】
:
: 对了,今天中午开会,一个老师痛斥C语言的“允许按值返回struct”这个特性,他告诉我compcert C编译器(一个验证过的C编译器)对struct返回值的处理和别的C编译器(当然以及平台ABI)有所区别,总之比较麻烦。看来人们都不喜欢C语言这个特性。
嗯,是这个意思。最简单的方法就是再传一个指针,指向一个调用者分配好的struct空间。函数把返回值往里写就行了。
【 在 wbzj1110 的大作中提到: 】
: 虽然明白细节。。但是大概意思就是不太推荐使用这个吧。。。太高端了。。有点听不懂。。
来自「北邮人论坛手机版」