将指向结构 (StructureByReference) 的指针传递给 C 代码,如何再次访问该数据?
Passing a pointer to a structure (StructureByReference) in to C code, How to access that data again?
我正在将 Android 中的 Java 中的以下测试结构传递给共享库中的本机 C 函数:
@Structure.FieldOrder({"testDouble", "testInt", "testPointer"})
public class Test extends Structure implements Structure.ByReference {
public double testDouble;
public int testInt;
public Pointer testPointer;
public Test(double testDouble, int testInt, Pointer testPointer) {
this.testDouble = testDouble;
this.testInt = testInt;
this.testPointer = testPointer;
}
Getters & Setters...
本机 C 代码将结构处理为:
void Test(double extraDouble, Test *TestResult)
本机 C 代码采用指向 TestResult
的指针并填充所有字段。
然后我需要能够在 Java 代码中访问该数据 - 即访问测试对象并读取数据 testDouble
、testInt
和 testPointer
,这是一个double[]
。 TestResult
对象没有被函数传回;如您所见,它只是在我假设的内存中被覆盖了。
我知道如何发送数据;然而,当我尝试通过 Java 中返回的值再次访问该对象时,在填充应该发生之后,我只得到零数据——就好像它是一个全新的对象,而不是原来的对象使用现在填充的数据。
如何访问我的 C 代码应该填充的数据? IE。我想再次访问该指针处的内存?
我假设在本机 C 代码中,它只是用新数据覆盖该内存块,然后我必须找到某种方法才能在 java 中访问该数据块并重建我的测试结构。如果我的任何推定不正确,请纠正我。
如果您需要任何说明,请告诉我。
C 结构就是:
typedef struct {
double testDouble;
int testInt;
double testPointer[3];
} Test;
您没有正确传递双精度数组。由于数组是固定大小的,您可以简单地将其映射为结构的一部分:
FieldOrder({"testDouble", "testInt", "testPointer"})
public class Test extends Structure {
public double testDouble;
public int testInt;
public double[] testPointer = new double[3];
// other code
}
这使您的结构总大小为 36 字节 (8 + 4 + 3x8)。目前使用 Pointer 你只传递 8 + 4 + 8 = 20 个字节。
这很容易解释为什么你没有得到任何双精度数,因为你只要求一个 8 字节的指针,但你需要 24 个字节的双精度数组。
不清楚为什么 double 和 int 没有填充。如果没有 Native API 的详细信息,我不确定它怎么知道你没有为它分配足够的内存,因为我的假设是它会尝试写前两个字段,将第三个字段写为数组中的第一个双精度数,然后可能会在尝试为剩余的两个双精度数写入分配的内存之外时崩溃。
您也没有说明如何将函数传递给本机端。您不需要包含 "ByReference",事实上,如果您使用它可能会导致问题,因为您必须在返回的结构上专门使用 "getValue()"。但是如果你像这样传递它(使用适当的映射)它应该工作:
映射:
void Test(double extraDouble, Test testResult)
通话:
Test testResult = new Test();
Test(extraDouble, testResult)
我正在将 Android 中的 Java 中的以下测试结构传递给共享库中的本机 C 函数:
@Structure.FieldOrder({"testDouble", "testInt", "testPointer"})
public class Test extends Structure implements Structure.ByReference {
public double testDouble;
public int testInt;
public Pointer testPointer;
public Test(double testDouble, int testInt, Pointer testPointer) {
this.testDouble = testDouble;
this.testInt = testInt;
this.testPointer = testPointer;
}
Getters & Setters...
本机 C 代码将结构处理为:
void Test(double extraDouble, Test *TestResult)
本机 C 代码采用指向 TestResult
的指针并填充所有字段。
然后我需要能够在 Java 代码中访问该数据 - 即访问测试对象并读取数据 testDouble
、testInt
和 testPointer
,这是一个double[]
。 TestResult
对象没有被函数传回;如您所见,它只是在我假设的内存中被覆盖了。
我知道如何发送数据;然而,当我尝试通过 Java 中返回的值再次访问该对象时,在填充应该发生之后,我只得到零数据——就好像它是一个全新的对象,而不是原来的对象使用现在填充的数据。
如何访问我的 C 代码应该填充的数据? IE。我想再次访问该指针处的内存?
我假设在本机 C 代码中,它只是用新数据覆盖该内存块,然后我必须找到某种方法才能在 java 中访问该数据块并重建我的测试结构。如果我的任何推定不正确,请纠正我。
如果您需要任何说明,请告诉我。
C 结构就是:
typedef struct {
double testDouble;
int testInt;
double testPointer[3];
} Test;
您没有正确传递双精度数组。由于数组是固定大小的,您可以简单地将其映射为结构的一部分:
FieldOrder({"testDouble", "testInt", "testPointer"})
public class Test extends Structure {
public double testDouble;
public int testInt;
public double[] testPointer = new double[3];
// other code
}
这使您的结构总大小为 36 字节 (8 + 4 + 3x8)。目前使用 Pointer 你只传递 8 + 4 + 8 = 20 个字节。
这很容易解释为什么你没有得到任何双精度数,因为你只要求一个 8 字节的指针,但你需要 24 个字节的双精度数组。
不清楚为什么 double 和 int 没有填充。如果没有 Native API 的详细信息,我不确定它怎么知道你没有为它分配足够的内存,因为我的假设是它会尝试写前两个字段,将第三个字段写为数组中的第一个双精度数,然后可能会在尝试为剩余的两个双精度数写入分配的内存之外时崩溃。
您也没有说明如何将函数传递给本机端。您不需要包含 "ByReference",事实上,如果您使用它可能会导致问题,因为您必须在返回的结构上专门使用 "getValue()"。但是如果你像这样传递它(使用适当的映射)它应该工作:
映射:
void Test(double extraDouble, Test testResult)
通话:
Test testResult = new Test();
Test(extraDouble, testResult)