[英]JNA how to pass String[] from Java to C code
我有一个问题。 我首先需要了解如何传递“String[] contentsStatic”。 我可以在 JNA 文档中看到 String[] 应该是 map 到 Char**。 我不确定如何在 Java 端使用 map。 在我的特定实现中,我什至不确定这是否真的有效,因为我尝试使用的 C 代码是 MatLab,因此在 C 代码中,它需要一个 'const emxArray_char_T *contentsStatic。 我不知道这是什么。
这是C这边:
Initialise(const emxArray_char_T *contentsStatic, const
emxArray_char_T *contentsDynamic, int b_phoneAngleDeg, double
b_stepCalibrationOffset, int b_initialFloorNumber, int
b_initialPointingAngleDeg, int b_initialAlignmentMode, bool *mapStatus, bool
*paramStatus);
Java 端是:
initialise(String[] contentsStatic,
String[] contentsDynamic,
int phoneRelativeToBodyDegree,
double initialStepCalibrationOffset,
int startingFloorID,
LatLng startingLatLong,
double startingAccuracy,
boolean _CDontActuallyUse,
int phoneOrientation,
int phoneOrientationUse,
boolean magntometerValid
)
作图方法供参考:
private struct MatWrap
{
var MatString: MatString
private var string_size_array_to_pass: [Int32]
private var string_bytes_int8: [Int8]
init(string: String)
{
let string_size = MatWrap.getSize(string: string)
self.string_bytes_int8 = MatWrap.getInt8Array(string: string)
self.string_size_array_to_pass = MatWrap.getSizeArray(size: string_size)
self.MatString = MatWrap.makeMatString(
data: &self.string_bytes_int8,
size: &self.string_size_array_to_pass,
allocatedSize: string_size
)
}
private static func getInt8Array(string: String) -> [Int8] {
let data = string.data(using: .ascii, allowLossyConversion: false)!
let bytes = [UInt8](data)
let bytes_int8 = bytes.map{Int8($0)}
return bytes_int8
}
private static func getSize(string: String) -> Int32 {
return Int32(string.lengthOfBytes(using: .ascii))
}
private static func getSizeArray(size: Int32) -> [Int32] {
return [1, size]
}
private static func makeMatString(data: UnsafeMutablePointer<Int8>, size: UnsafeMutablePointer<Int32>, allocatedSize: Int32) -> MatString {
return MatString(data: data, size: size, allocatedSize: allocatedSize, numDimensions: 1, canFreeData: false)
}
}
用于准备连接的 String[] 以传递的方法:
allFloorsDynamic_wrappedMatString = MatWrap(string: contentsDynamic.joined())
您在询问如何传递String[]
但这不是本机 function 所期望的。
查看Matlab 文档, emxArray_char_T
是一个结构:
struct emxArray_char_T
{
char * str;
int size;
};
此外,阅读文档,您可以看到 API 的描述:
代码生成器生成 C/C++ 数组定义,这些定义取决于数组元素类型以及数组是使用 static 还是动态 memory 分配。 数组的两种 memory 分配需要两种不同的实现:
对于大小在预定义阈值范围内的数组,生成的 C/C++ 定义包含指向 memory 的指针和存储数组元素总数(数组大小)的 integer。 该数组的 memory 来自程序堆栈,是静态分配的。
对于在编译时大小未知且无界的数组,或者其界限超过预定义阈值的数组,生成的 C/C++ 定义包含一个称为 emxArray 的数据结构。 创建 emxArray 时,会根据当前数组大小设置中间存储边界。 在程序执行期间,由于超出了中间存储边界,生成的代码会从堆中占用额外的 memory 空间并将其添加到 emxArray 存储中。 该数组的 memory 是动态分配的。
对于将const
值传递给本机端的情况,您可以使用静态分配的版本。 但是,在这里您会遇到 JNA 的限制:定义结构时必须知道 arrays 的大小。 所以要使用一个结构,你必须这样做:
@FieldOrder ({"str", "size"})
class emxArray_char_T_3 extends Structure {
public String[] strArray = new String[3];
public int size = 3;
}
您可以定义它,然后设置 3 个strArray
元素。 你可以为不同的大小做一个类似的数组。
但是,看起来 MATLAB 具有用于创建此数组的辅助函数,例如emxCreateWrapper_char_T
。 您可能想弄清楚如何使用它们。
进一步深入研究文档, 他们说:
如果您不使用动态 memory 分配,则结构中的 arrays 将转换为一维 arrays,而不是指针。
这对字符串来说是一个挑战,字符串的长度是可变的 arrays,而其他语言的典型String[]
映射将是指向其他地方字符串的指针数组。 这意味着要直接使用具有const
类型的现有结构,您必须为字符串定义定长字符 arrays。
查看您在编辑中添加的字符串 arrays 的语法,看起来您仍然必须传递单个字符串,但joined
的符号意味着它需要某种分隔符号。 同样,您必须搜索 API 才能准确找到分隔符!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.