Jna,随机无效内存访问错误

时间:2018-02-22 10:05:48

标签: java kotlin jna

我有openvr binding,因为一段时间有一个小问题

基本上,每当我释放一些几何3d模型(基站或控制器)的内存时,我会得到Error

  

" java.lang.Error:内存访问无效"

这是test我到目前为止使用的,它加载并释放了Steam安装文件夹中存在的模型列表的x倍:

for (i in 0..99)   models.forEach(::loadRenderModel)

fun loadRenderModel(renderModelName: String) {

    var error: EVRRenderModelError

    val rm = vrRenderModels!!

    val pModel = PointerByReference()
    while (true) {
        error = rm.loadRenderModel_Async(renderModelName, pModel)
        if (error != EVRRenderModelError.Loading) break
        Thread.sleep(1)
    }
    val model = RenderModel.ByReference(pModel.value)

    if (error != EVRRenderModelError.None) {
        System.err.println("Unable to load render model $renderModelName - ${error.getName()}")
        return // move on to the next tracked device
    }

    try {
        rm freeRenderModel model
    } catch (e: Error) {
        System.err.println(e)
    }
    println()
}
C++中的

RenderModel结构:

struct RenderModel_t
{
    const RenderModel_Vertex_t *rVertexData;    // Vertex data for the mesh
    uint32_t unVertexCount;                     // Number of vertices in the vertex data
    const uint16_t *rIndexData;                 // Indices into the vertex data for each triangle
    uint32_t unTriangleCount;                   // Number of triangles in the mesh. Index count is 3 * TriangleCount
    TextureID_t diffuseTextureId;               // Session unique texture identifier. Rendermodels which share the same texture will have the same id. <0 == texture not present
};

并在Kotlin中:

open class RenderModel : Structure {

    /** Vertex data for the mesh    */
    @JvmField
    var rVertexData: RenderModel_Vertex.ByReference? = null
    /** Number of vertices in the vertex data   */
    @JvmField
    var vertexCount = 0
    /** Indices into the vertex data for each triangle  */
    @JvmField
    var rIndexData: ShortByReference? = null
    /** Number of triangles in the mesh. Index count is 3 * TriangleCount   */
    @JvmField
    var triangleCount = 0
    /** Session unique texture identifier. Rendermodels which share the same texture will have the same id. <0 == texture not present   */
    @JvmField
    var diffuseTextureId = INVALID_TEXTURE_ID

    val vertices
        get() = rVertexData?.pointer?.getByteArray(0, vertexCount * RenderModel_Vertex.SIZE)

    val indices
        get() = rIndexData?.pointer?.getByteArray(0, triangleCount * 3 * Short.BYTES)

    constructor()

    constructor(vertexData: RenderModel_Vertex.ByReference, vertexCount: Int, indexData: ShortByReference, triangleCount: Int,
                diffuseTextureId: Int) {
        this.rVertexData = vertexData
        this.vertexCount = vertexCount
        this.rIndexData = indexData
        this.triangleCount = triangleCount
        this.diffuseTextureId = diffuseTextureId
    }

    override fun getFieldOrder()= listOf("rVertexData", "vertexCount", "rIndexData",
            "triangleCount", "diffuseTextureId")

    constructor(peer: Pointer) : super(peer) {
        read()
    }

    class ByReference : RenderModel, Structure.ByReference {
        constructor() : super()
        constructor(peer: Pointer) : super(peer)
    }

    class ByValue : RenderModel(), Structure.ByValue
}

我倾向于相信到目前为止(关于类定义)的所有内容都是正确的,因为我确实读过有效值。

但是我不时会收到这个错误,我检查了一些指针值,我没有发现任何奇怪的值

它有什么用?

1 个答案:

答案 0 :(得分:1)

我在您的代码中发现了一个错误,但我无法确认这是您失败的原因。它肯定可以生成它们。

你说

val error = EVRRenderModelError.None

然后

if (error != EVRRenderModelError.None) {

这是一个不断false的条件。通常情况下,IntelliJ检查会警告您这些错误,但可以在配置中禁用它。

您应该使用var error,并在异步调用的busy-wait循环中重新分配。