我有一个我想在Unity(C#)中使用的C ++类,所以我编译了一个C ++ dll并为它创建了一个C#包装器。我是用SWIG做的。
当我这样做时:
Graph g = new Graph();
int k = g.AddNode();
没关系,我尝试使用Debug.Log(k)检查返回的k值,看起来似乎正常。所以我认为我可以调用函数并返回值。
但是当我尝试这样做时,Unity会崩溃:
g.AddNode(num_of_nodes);
似乎每次尝试发送值时都会崩溃。不知道为什么会这样。
我要包装的课程是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;
}
答案 0 :(得分: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进行调试。