向c#封装的c++ dll发送值会导致Unity崩溃



我有一个c++类,我想在Unity(c#)中使用,所以我编译了一个c++ dll并为它创建了一个c#包装器dll。我使用SWIG完成了这个操作。

当我这样做时:

Graph g = new Graph();
int k = g.AddNode();

很好,我尝试了Debug.Log(k)来检查返回的k值,它似乎工作正常。所以我认为我可以调用函数并获得返回值

但是当我尝试这样做时,Unity会崩溃:

g.AddNode(num_of_nodes);

似乎它会崩溃每当我试图发送值。不知道为什么会这样。


我想包装的类是Yuri Boykov和Vladimir Kolmogorov的MaxFlow库。如果有人对如何在Unity中使用这个库有任何想法,请帮助。

原始c++ add_node()函数:

int Graph::add_node(int num)
{
    //assert(num > 0);
    if (node_last + num > node_max) reallocate_nodes(num);
    if (num == 1)
    {
        node_last -> first = NULL;
        node_last -> tr_cap = 0;
        node_last -> is_marked = 0;
        node_last -> is_in_changed_list = 0;
        node_last ++;
        return node_num ++;
    }
    else
    {
        memset(node_last, 0, num*sizeof(node));
        int i = node_num;
        node_num += num;
        node_last += num;
        return i;
    }
}

SWIG生成*_wrap。cxx, AddNode的功能:

//with send param (g.AddNode(num_of_nodes)), this one will crash
SWIGEXPORT int SWIGSTDCALL CSharp_Graph_add_node__SWIG_0(void * jarg1, int jarg2) {
  int jresult ;
  MaxFlowGraph::Graph *arg1 = (MaxFlowGraph::Graph *) 0 ;
  int arg2 ;
  MaxFlowGraph::Graph::int result;
  arg1 = (MaxFlowGraph::Graph *)jarg1; 
  arg2 = (int)jarg2; 
  result = (arg1)->add_node(arg2);
  jresult = result; 
  return jresult;
}
//without send param (g.AddNode()), this one works
SWIGEXPORT int SWIGSTDCALL CSharp_Graph_add_node__SWIG_1(void * jarg1) {
  int jresult ;
  MaxFlowGraph::Graph *arg1 = (MaxFlowGraph::Graph *) 0 ;
  MaxFlowGraph::Graph::int result;
  arg1 = (MaxFlowGraph::Graph *)jarg1; 
  result = (arg1)->add_node();
  jresult = result; 
  return jresult;
}

SWIG生成的cs文件,AddNode函数:

public int AddNode(int num)
{
    int ret = MaxFlowGraphPINVOKE.Graph_add_node__SWIG_0(swigCPtr, num);
    return ret;
}
public int AddNode()
{
    int ret = MaxFlowGraphPINVOKE.Graph_add_node__SWIG_1(swigCPtr);
    return ret;
}

也许不是你想要的答案,但这是我能根据这个问题想出的最好的答案。

我将从一个简单的例子开始,从那里开始。例如,首先修改函数,使其只做返回,如下所示:

int Graph::add_node(int num)
{
    return 1;
}

那也会崩溃吗?如果是这样,那么问题不在函数中,而可能在包装器代码中。也许修改包装器代码也不做任何事情:

SWIGEXPORT int SWIGSTDCALL CSharp_Graph_add_node__SWIG_0(void * jarg1, int jarg2) {
   return 1;
}

还会崩溃吗?如果是这样,可能是减速问题或不正确的编译器设置(混合调用约定,32位与64位,不兼容的库或外部依赖等)。

如果上面的第一个修复了崩溃,那么很可能是代码中的错误,就像我怀疑memset()一样——我会开始向函数中添加越来越多的代码,直到它再次崩溃,以找出崩溃发生的确切位置。

这些都是假设您无法使用调试器逐步完成的—我假设如果您可以这样做,那么您就不会首先问这个问题。如果你能提供更多的细节,比如上面测试的结果,我将尽力帮助你。

编辑:如果它在崩溃之前到达您的c++代码,您可以尝试使用OutputDebugString进行调试。

最新更新