- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我在带有 JNA 框架的 Java 应用程序中使用 native c++ dll。我在调用函数时遇到问题。也许我没有正确分配内存?我没有意见,接下来要尝试什么。我没有获得任何更多信息来帮助我摆脱文档和论坛主题。我希望你能给我一个提示,那就太好了。
我想调用 native 函数(例如 FooInterface
)。此函数采用结构 TNativeFoo
作为输入和输出参数。结构 TNativeFoo
包含一个 Double**
/Double[][]
数据。该字段可以看作是一个多维数组,但第一维的长度仅为 1。因此它更像是一个指向大小为 Items
的 double 组的指针。
结构(char**
/String[]
)中还有一个StringArray
,长度为StringsCount
,这是无关紧要的,因为它没有被使用。我提到它是因为我不确定错误是否与此有关。下面是对原生dll的定义和结构。
public interface Foodll extends StdCallLibrary {
Foodll INSTANCE = (Foodll) Native.loadLibrary("foodll.dll", Foodll.class);
public static class TNativeFoo extends com.sun.jna.Structure {
public TNativeFoo (){
super();
setAlignType(ALIGN_NONE);
}
public TNativeFoo(com.sun.jna.Pointer pointer,int offset) {
super();
setAlignType(ALIGN_NONE);
useMemory(pointer,offset);
read();
}
public TNativeFoo(TNativeFoo struct) {
this(struct.getPointer(),0);
}
public static class ByReference extends TNativeFoo implements com.sun.jna.Structure.ByReference {
ByReference() {}
ByReference(TNativeFoo struct){super(struct.getPointer(),0);}
}
public static class ByValue extends TNativeFoo implements com.sun.jna.Structure.ByValue {
ByValue() {}
ByValue(TNativeFoo struct){super(struct.getPointer(),0);}
}
public PointerByReference Data;
public NativeLong Items;
public PointerByReference IrrelevantStringArray;
public NativeLong StringsCounts = new NativeLong(0);
}
NativeLong FooInterface(TNativeFoo input, TNativeFoo output);
}
对于函数的调用,我尝试在 native 堆上分配内存并将数据写入其中。在像示例中那样将数据写入 native 堆后,我可以像在示例中使用备选方案 2 那样读取它(我在不调用 native 函数的情况下直接从 inputFoo
尝试了此操作)。像下面的示例一样调用 native 函数会引发致命异常。
调用:
public class FooInvocationClass
{
public static FooInvocationMethod(double[] fooData)
{
Foodll foodllJnaLib = Foodll.INSTANCE;
Foodll.TNativeFoo outputFoo = new Foodll.TNativeFoo();
Foodll.TNativeFoo inputFoo = new Foodll.TNativeFoo();
//Writing input data to the native heap
Memory dataPointer = new Memory (fooData.length * Double.SIZE);
dataPointer.write(0, fooData, 0, fooData.length);
inputFoo.Data = new PointerByReference();
inputFoo.Data.setValue(dataPointer);
outputProfile.Data = new PointerByReference();
inputFoo.Items = outputFoo.Items = new NativeLong(fooData.length);
//Setting some irrelevant StringArray Parameters
inputFoo.IrrelevantStringArray = outputFoo.IrrelevantStringArray = new PointerByReference();
inputFoo.StringsCounts = outputFoo.StringsCounts = new NativeLong(0);
//Invocation
foodllJnaLib.FooInterface(inputFoo, outputFoo);
//Reading Output
Pointer outputFooDataPointer = outputFoo.Data.getValue();
//Reading Output alternative 1
Double[] outDataAlt1 = outputFooDataPointer.getDoubleArray(0, outputFoo.items);
//Reading Output alternative 2
Double[] outDataAlt2 = new Double[outputFoo.items];
for (int x = 0; x < outputFoo.items; x += 1)
{
outDataAlt2[x] = outputFooDataPointer.getDouble(x * 8);
}
}
}
异常(exception):
# A fatal error has been detected by the Java Runtime Environment:
#
# Internal Error (0x0), pid=5904, tid=220
#
# JRE version: 7.0_04-b22
# Java VM: Java HotSpot(TM) Client VM (23.0-b21 mixed mode, sharing windows-x86 )
# Problematic frame:
# C [KERNELBASE.dll+0xb9bc] RaiseException+0x58
#
# Failed to write core dump. Minidumps are not enabled by default on client versions of Windows
#
# An error report file with more information is saved as:
# E:\Programme\apache-tomcat-7.0.27\bin\hs_err_pid5904.log
#
我也可以想象在 64 位系统上运行的 32 位 JVM 和 native 代码存在问题。我在我的 64 位系统上安装了一个 32 位 JVM,因为我遇到了 JNA“找不到 native dll”的问题。
我发现我犯了一个错误,我查看了错误的 Structure 定义,它看起来一样,但不是。所以我必须改变我的问题。
但我也提出我的问题是错误的,我尝试了大家提出的建议。它们帮助我理解了主题,在找到正确的结构定义后我尝试了它们。谢谢你。
但异常保持不变。也许我在代码中有不止一个错误。所以我的问题又来了,希望现在是正确的,并且比以前有更多的信息。必须 Foo 一些东西(关于公司),但语义保持不变。
我真的没有 h 文件或源代码。我很晚才进入这个项目,而且我只是兼职工作。其他人正在使用 C++/CLI 编写 native 调用程序,并且成功了。所以我附上了下面的代码。 c++/CLI 代码下方是更改后的 Java 代码。
typedef void (__stdcall *TFooInterface) (
LONGLONG *APrgId,
void *input,
void *output,
double value,
HANDLE AAppHandle,
HANDLE AProgessBar,
char *AText,
char **ReturnText
);
//-APrgID is a ID, which tells the Method, what type of processing it should do.
//-The void Pointers both take a TNativeFOO Structure. One is for the input, the other one is for the output.
//-The double-value is a Parameter for the algorithm.
//-The Handle Parameters are for a programm, the dll was created for. They give status about the processing or something like that. We now use the dll in an other context, so they aren't needed anymore.
//-char *AText amd. char **ReturnText are, also not needed anymore. They are for exception handling as far as I know. We handle the Exception in the new Context more general.
typedef struct {
double *Data;
long Items;
unsigned char *String;
long StringCounts;
double Value1, Value2;
char *FileName;
char *DataObject;
char *Comment;
bool Valid;
} TNativeFoo;
//-*Data is a double Array holding the data to process in TFooInterface
//-Items is the lenght of Data
//-*String and StringCounts are not needed anymore, because the dll is used in another way. I can't tell what it is for.
//-Value1, Value2 are Parameters used in the algorithm
//-FileName is for storing the result. Isn't used.
//-DataObject, Comment is also never used. I can't tell what it is for.
//-Valid is a success-flag of the algorithm.
void FooClass::FooIt(double[] FooData, HMODULE hFooLib)
{
TNativeFoo Input, Output; //Declaration of the Structures
LONGLONG PrgID;
LONGLONG ID;
double value;
double[] OutputData = new double[FooData.length];
ID =-35547318716283305;
//setting up the Structures
memset(&Input, 0, sizeof(TNativeFoo));
memset(&Output, 0, sizeof(TNativeFoo));
Output.Data = new double[FooData.length];
Input.Data = &(FooData[0]);
Input.Items = Output.Items = FooData.length;
Input.Value1 = Output.Value1 = 1.3;
Input.Value2 = Output.Value2 = 2.3;
Input.Valid = Output.Valid = true;
FooInterface = (TFooInterface) GetProcAddress(hFooLib, "FooInterface");
FooInterface(&ID, &Input, &Output, value, 0, 0, "", NULL);
for (long i=0; i<Output.Items; i++)
{
OutputData[i]= Output.Data[i];
}
...
}
public interface Foodll extends StdCallLibrary {
Foodll INSTANCE = (Foodll) Native.loadLibrary("foodll.dll", Foodll.class);
//Structure
public static class TNativeFoo extends com.sun.jna.Structure {
public TNativeFoo(){
setAlignType(Structure.ALIGN_NONE);
}
public TNativeFoo(com.sun.jna.Pointer pointer, int offset) {
super(pointer.share(offset));
setAlignType(Structure.ALIGN_NONE); //Tested all align-types. I was told this is the one used by the dlls
read();
}
public TNativeFoo(TNativeProfile struct) {
super(struct.getPointer());
setAlignType(Structure.ALIGN_NONE); //Tested all align-types. I was told this is the one used by the dlls
read();
}
public static class ByReference extends TNativeFoo implements com.sun.jna.Structure.ByReference {
ByReference() {}
ByReferenceTNativeFoo struct){super(struct.getPointer(),0);}
}
public static class ByValue extends TNativeFoo implements com.sun.jna.Structure.ByValue {
ByValue() {}
ByValueTNativeFoo struct){super(struct.getPointer(),0);}
}
public Pointer Data;
public double[] getData() {
if (this.Data == null) return null;
return this.Data.getDoubleArray(0, Items.intValue());
}
public void setData(double[] data) {
if (this.Data == null) {
this.Data = new Memory(data.length * 8);
}
this.Data.write(0, data, 0, data.length);
}
public NativeLong Items;
public String String;
public NativeLong StringCounts = new NativeLong(0);
public double Value1;
public double Value2;
public String FileName;
public String DataObject;
public String Comment;
public boolean Valid;
}
NativeLong FooInterface(DoubleByReference prgid, TNativeFoo input, TNativeFoo output, double value, Pointer aAppHandle, Pointer aProgessBar, String AText, String[] ReturnText);
}
public class FooInvocationClass
{
public static FooInvocationMethod(double[] fooData, ID)
{
Foodll foodllJnaLib = Foodll.INSTANCE;
Foodll.TNativeFoo outputFoo = new Foodll.TNativeFoo();
Foodll.TNativeFoo inputFoo = new Foodll.TNativeFoo();
inputFoo.setData(fooData);
outputFoo.setData(new double[fooData.length]);
inputFoo.Items = outputFoo.Items = new NativeLong(fooData.length);
inputFoo.String = outputFoo.String = "";
inputFoo.StringCounts = outputFoo.StringCounts = new NativeLong(0);
inputFoo.Value1 = outputFoo.Value1 = 0.1;
inputFoo.Value2 = outputFoo.Value2 = 0.3;
Double ID =-35547318716283305;
double value = 0.025;
impDriveFiltJnaLib.ProfileFilterInterface(new DoubleByReference(ID), input, output, value, null, null, null, null);
Double[] outDataAlt1 = outputFoo.getDate();
}
}
在我解决了 dll 中的文件错误问题后,异常发生了变化。必须再次复制 dll。这解决了无法加载 dll 的问题。
#
# A fatal error has been detected by the Java Runtime Environment:
#
# EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x027047b8, pid=800, tid=7584
#
# JRE version: 7.0_04-b22
# Java VM: Java HotSpot(TM) Client VM (23.0-b21 mixed mode, sharing windows-x86 )
# Problematic frame:
# C [FooDll.dll+0x47b8] FooInterface+0x2288
#
# Failed to write core dump. Minidumps are not enabled by default on client versions of Windows
#
# An error report file with more information is saved as:
# E:\Programme\apache-tomcat-7.0.27\bin\hs_err_pid800.log
#
# If you would like to submit a bug report, please visit:
# http://bugreport.sun.com/bugreport/crash.jsp
# The crash happened outside the Java Virtual Machine in native code.
# See problematic frame for where to report the bug.
#
最佳答案
我有两个建议:-
您应该尝试使用 jnaerator 为给定的 c/c++ header 生成 java 代码。 (这将是一个很好的起点)。
根据环境,您的 native double / float 大小将不同于 Java double / float 。即 native double 可能等于 Java float 。所以你也需要检查一下。
因此,您需要对不同的结构组合进行一些自己的分析,以准确了解本地人想要的内容。如果您没有准确通过,则会导致崩溃。
也请发布您的答案。
关于java - JNA native 函数调用和具有 Double**-Pointer/Array 内存分配的结构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10688120/
为了让我的代码几乎完全用 Jquery 编写,我想用 Jquery 重写 AJAX 调用。 这是从网页到 Tomcat servlet 的调用。 我目前情况的类似代码: var http = new
我想使用 JNI 从 Java 调用 C 函数。在 C 函数中,我想创建一个 JVM 并调用一些 Java 对象。当我尝试创建 JVM 时,JNI_CreateJavaVM 返回 -1。 所以,我想知
环顾四周,我发现从 HTML 调用 Javascript 函数的最佳方法是将函数本身放在 HTML 中,而不是外部 Javascript 文件。所以我一直在网上四处寻找,找到了一些简短的教程,我可以根
我有这个组件: import {Component} from 'angular2/core'; import {UserServices} from '../services/UserService
我正在尝试用 C 实现一个简单的 OpenSSL 客户端/服务器模型,并且对 BIO_* 调用的使用感到好奇,与原始 SSL_* 调用相比,它允许一些不错的功能。 我对此比较陌生,所以我可能会完全错误
我正在处理有关异步调用的难题: 一个 JQuery 函数在用户点击时执行,然后调用一个 php 文件来检查用户输入是否与数据库中已有的信息重叠。如果是这样,则应提示用户确认是否要继续或取消,如果他单击
我有以下类(class)。 public Task { public static Task getInstance(String taskName) { return new
嘿,我正在构建一个小游戏,我正在通过制作一个数字 vector 来创建关卡,该数字 vector 通过枚举与 1-4 种颜色相关联。问题是循环(在 Simon::loadChallenge 中)我将颜
我有一个java spring boot api(数据接收器),客户端调用它来保存一些数据。一旦我完成了数据的持久化,我想进行另一个 api 调用(应该处理持久化的数据 - 数据聚合器),它应该自行异
首先,这涉及桌面应用程序而不是 ASP .Net 应用程序。 我已经为我的项目添加了一个 Web 引用,并构建了各种数据对象,例如 PayerInfo、Address 和 CreditCard。但问题
我如何告诉 FAKE 编译 .fs文件使用 fsc ? 解释如何传递参数的奖励积分,如 -a和 -target:dll . 编辑:我应该澄清一下,我正在尝试在没有 MSBuild/xbuild/.sl
我使用下划线模板配置了一个简单的主干模型和 View 。两个单独的 API 使用完全相同的配置。 API 1 按预期工作。 要重现该问题,请注释掉 API 1 的 URL,并取消注释 API 2 的
我不确定什么是更好的做法或更现实的做法。我希望从头开始创建目录系统,但不确定最佳方法是什么。 我想我在需要显示信息时使用对象,例如 info.php?id=100。有这样的代码用于显示 Game.cl
from datetime import timedelta class A: def __abs__(self): return -self class B1(A):
我在操作此生命游戏示例代码中的数组时遇到问题。 情况: “生命游戏”是约翰·康威发明的一种细胞自动化技术。它由一个细胞网格组成,这些细胞可以根据数学规则生存/死亡/繁殖。该网格中的活细胞和死细胞通过
如果我像这样调用 read() 来读取文件: unsigned char buf[512]; memset(buf, 0, sizeof(unsigned char) * 512); int fd;
我用 C 编写了一个简单的服务器,并希望调用它的功能与调用其他 C 守护程序的功能相同(例如使用 ./ftpd start 调用它并使用 ./ftpd stop 关闭该实例)。显然我遇到的问题是我不知
在 dos 中,当我粘贴此命令时它会起作用: "C:\Program Files (x86)\Google\Chrome\Application\chrome.exe" https://google.
在 dos 中,当我粘贴此命令时它会起作用: "C:\Program Files (x86)\Google\Chrome\Application\chrome.exe" https://google.
我希望能够从 cmd 在我的 Windows 10 计算机上调用 python3。 我已重新安装 Python3.7 以确保选择“添加到路径”选项,但仍无法调用 python3 并使 CMD 启动 P
我是一名优秀的程序员,十分优秀!