退出对抽象类型的项目进行迭代的C ++ FFI调用时的Haxe / Neko异常

时间:2019-02-25 00:25:07

标签: c++ haxe neko

当我返回一个抽象类型的value时,其中包含来自一个FFI的向量,并在另一个FFI中对其进行迭代,因此在第二个FFI调用结束时会出现异常。我可以毫无问题地一一访问向量中的项目,但是遍历值似乎会引起问题。我是否对每个循环,迭代器甚至对索引循环都没关系。

哈希码:

class VectorExample {
    public static function main() {
        var vec = createVec();
        // dumpForIntIter(vec); // fails on exit
        dumpEach(vec);          // works
    }

    private static var createVec = neko.Lib.load("vectorLib", "createVec", 0);
    private static var dumpForIntIter = neko.Lib.load("vectorLib", "dumpForIntIter", 1);
    private static var dumpEach = neko.Lib.load("vectorLib", "dumpEach", 1);
}

Cpp代码:

#include <iostream>
#include <string>
#include <vector>
#include <neko.h>

void free_vec( value handle ) {
    std::cout << "freeing vec" << std::endl;
    std::vector<std::string>* vec = (std::vector<std::string>*) val_data(handle);
    delete vec;
}

DEFINE_KIND(k_vector);

value createVec() {
    auto vec = new std::vector<std::string>();
    vec->push_back(std::string("one"));
    vec->push_back(std::string("two"));
    vec->push_back(std::string("three"));

    value handle = alloc_abstract(k_vector, vec);
    val_gc(handle, free_vec);

    return handle;
}
DEFINE_PRIM(createVec,0);

// fails on exit
void dumpForIntIter( value handle ) {
    auto vec = (std::vector<std::string>*) val_data(handle);
    std::cout << "size: " << vec->size() << std::endl;
    for (int ii=0; ii<vec->size(); ii++)
        std::cout << "  item: " << vec->at(ii) << std::endl;
}
DEFINE_PRIM(dumpForIntIter,1);

// works
void dumpEach( value handle ) {
    int ii = 0;
    auto vec = (std::vector<std::string>*) val_data(handle);
    std::cout << "size: " << vec->size() << std::endl;
    std::cout << "  item: " << vec->at(0) << std::endl;
    ii++;
    std::cout << "  item: " << vec->at(1) << std::endl;
    ii++;
    std::cout << "  item: " << vec->at(2) << std::endl;
    ii++;
}
DEFINE_PRIM(dumpEach,1);

构建Neko模块的命令:

g++ -o vectorLib.ndll -shared -fPIC -std=c++11 -I/usr/include/x86_64-linux-gnu \
    -L/usr/lib/x86_64-linux-gnu -lneko -ldl vectorLib.cpp

使用dumpForIntIter运行时的输出:

size: 3
  item: one
  item: two
  item: three
freeing vec
Called from ? line 1
Called from VectorExample.hx line 6
Uncaught exception - vectorLib@dumpForIntIter

请注意,尽管freeing vec是日志中的最后一件事,但是即使free_vec为空或不存在,也会出现问题。

由于dumpForIntIterdumpForEach基本上与我等效,因此我怀疑createVec中存在问题。

文档:Neko FFI

更新:

我禁用了nekovm中的异常陷阱,并发现问题是段错误。这是valgrind的输出:

Jump to the invalid address stated on the next line
   at 0x2A50DA10C1C9AED6: ???
 Address 0x2a50da10c1c9aed6 is not stack'd, malloc'd or (recently) free'd

Can't extend stack to 0x2a50da10c1c99f88 during signal delivery for thread 1:
  no stack segment

Process terminating with default action of signal 11 (SIGSEGV)
 Access not within mapped region at address 0x2A50DA10C1C99F88
   at 0x2A50DA10C1C9AED6: ???

更新2:

如果我将vector<string>更改为vector<int>,问题仍然存在。如果我更改为char**(使用mallocnew),就没有问题。如果我只更改为string,那没有问题。好像alloc_abstract不喜欢vector

0 个答案:

没有答案