首页 文章

将值发送到C#包装的C dll会导致Unity崩溃

提问于
浏览
4

我有一个我想在Unity(C#)中使用的C类,所以我编译了一个C dll并为它创建了一个C#wrapper dll . 我是用SWIG做的 .

当我这样做:

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

没关系,我尝试使用Debug.Log(k)检查返回的k值,看起来似乎正常 . 所以我认为 I can call functions and get returning values .

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

g.AddNode(num_of_nodes);

似乎 it will crash whenever I try to send values . 不知道为什么会这样 .


我想要包装的类是MaxFlow library of Yuri Boykov and Vladimir Kolmogorov . 任何人都知道如何在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 grnerated 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;
}

1 回答

  • 0

    也许不是你想要的答案,但我可以根据这个问题提出最好的答案 .

    我将从一个更简单的例子开始,然后从那里开始工作 . 例如,首先修改你的函数除了返回之外什么都不做,像这样:

    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进行调试 .

相关问题