#java #c #pass-by-reference #jna
#java #c #передача по ссылке #jna
Вопрос:
Ниже приведены классы, которые я использую в своем приложении для извлечения значений в качестве ссылки из библиотеки C.
public class ShingleCoOrdJNAList extends Structure {
public static class ByValue extends ShingleCoOrdJNAList implements Structure.ByValue {}
public static class ByReference extends ShingleCoOrdJNAList implements Structure.ByReference {}
public ByReference size;
public ShingleCoOrdJNA.ByReference shingleCoords;
@Override
protected List getFieldOrder() {
return Arrays.asList(new String[] { "size","shingleCoords"});
}
}
public class ShingleCoOrdJNA extends Structure {
public static class ByReference extends ShingleCoOrdJNA implements Structure.ByReference {}
public static class ByValue extends ShingleCoOrdJNA implements Structure.ByValue {}
public Point.ByValue ShiP1;
public Point.ByValue ShiP2;
public Point.ByValue ShiP3;
public Point.ByValue ShiP4;
public Point.ByReference vDamagePts;
public boolean bIsGood;
public float fDamagePercentage;
public ShingleCoOrdJNA()
{
this.bIsGood = true;
this.fDamagePercentage = 0;
}
@Override
protected List getFieldOrder() {
return Arrays.asList(new String[] { "ShiP1","ShiP2","ShiP3","ShiP4","vDamagePts","bIsGood","fDamagePercentage"});
}
}
public class Point extends Structure {
public static class ByValue extends Point implements Structure.ByValue { }
public static class ByReference extends Point implements Structure.ByReference { }
public double x;
public double y;
@Override
protected List getFieldOrder() {
return Arrays.asList(new String[] { "x","y"});
}
}
Я вызываю библиотеку C, как показано ниже, из java
ShingleCoOrdJNAList.ByReference shingleCoordList = new ShingleCoOrdJNAList.ByReference();
IntByReference size = new IntByReference();
TestImgProcInterface.INSTANCE.callPerformShingleDetection(newMat.getNativeObjAddr(), pointList, 4, shingleCoordList, size, false, true);
Ниже приведен код C
extern "C" void callPerformShingleDetection(Mat amp;FrameMat, struct PointListJNA pointList, int pointSize, struct ShingleCoOrdJNAList amp;damagePts, int amp;damagePtsSize, bool bShowResult, bool bDoDamageAnalysis) {
vector<cv::Point> vPolyList;
Point pXY;
for(int i=0;i<pointSize;i ) {
pXY.x = pointList.points[i].x;
pXY.y = pointList.points[i].y;
vPolyList.push_back(pXY);
}
vector<ShingleCoOrd> vShingleList;
PerformShingleDetection(FrameMat, vPolyList, vShingleList, bShowResult, bDoDamageAnalysis);
std::cout << "Image processing completed" << endl;
damagePts = {};
damagePts.size = vShingleList.size();
damagePts.shingleCoords = (ShingleCoOrdJNA*)malloc(sizeof(ShingleCoOrdJNA) * vShingleList.size());
for(int j=0;j<vShingleList.size();j ) {
damagePts.shingleCoords[j].ShiP1 = getJNAPoint(vShingleList[j].ShiP1);
damagePts.shingleCoords[j].ShiP2 = getJNAPoint(vShingleList[j].ShiP2);
damagePts.shingleCoords[j].ShiP3 = getJNAPoint(vShingleList[j].ShiP3);
damagePts.shingleCoords[j].ShiP4 = getJNAPoint(vShingleList[j].ShiP4);
damagePts.shingleCoords[j].bIsGood = vShingleList[j].bIsGood;
damagePts.shingleCoords[j].fDamagePercentage = vShingleList[j].fDamagePercentage;
damagePts.shingleCoords[j].vDamagePts = (Points*)malloc(sizeof(Points) * vShingleList[j].vDamagePts.size());
for(int m=0;m<vShingleList[j].vDamagePts.size();m ) {
damagePts.shingleCoords[j].vDamagePts[m] = getJNAPoint(vShingleList[j].vDamagePts[m]);
}
std::cout << "vShingleList[j].vDamagePts.size()" << vShingleList[j].vDamagePts.size() << endl;
}
std::cout << "Size of shingle detected" << vShingleList.size() << endl;
}
Я получаю сообщение об ошибке, как показано ниже.
#
# A fatal error has been detected by the Java Runtime Environment:
#
# SIGSEGV (0xb) at pc=0x00007f45cdbfd6a7, pid=11278, tid=0x00007f46340a9700
#
# JRE version: Java(TM) SE Runtime Environment (8.0_101-b13) (build 1.8.0_101-b13)
# Java VM: Java HotSpot(TM) 64-Bit Server VM (25.101-b13 mixed mode linux-amd64 compressed oops)
# Problematic frame:
# C [jna7588690608297773974.tmp 0x96a7] Java_com_sun_jna_Native__1getPointer 0xc7
#
# Failed to write core dump. Core dumps have been disabled. To enable core dumping, try "ulimit -c unlimited" before starting Java again
#
# An error report file with more information is saved as:
# /home/user1/workspace/ImageProcessor/hs_err_pid11278.log
#
# If you would like to submit a bug report, please visit:
# http://bugreport.java.com/bugreport/crash.jsp
# The crash happened outside the Java Virtual Machine in native code.
# See problematic frame for where to report the bug.
#
Я могу печатать все выполнения в классе C. Но не могу вернуть данные в моем классе Java. Единственная проблема заключается в том, когда я передаю vDamagePts в моем классе C. В остальном все работает нормально.
Комментарии:
1. Какое значение
vShingleList[j].vDamagePts.size()
перед выделениемdamagePts.shingleCoords[j].vDamagePts
, поскольку оно еще не создано?2. @ecle : это значение мы получаем из другой библиотеки. Мы правильно получаем значение из этой библиотеки.
3. Пожалуйста, включите также объявления структур C. Обратите внимание на этот момент. ByValue является излишним в качестве поля структуры; семантика по значению является значением по умолчанию в этом контексте.