Отправка значений в С#, обернутую в С++ dll, вызывает сбой Unity

У меня есть класс C++, который я хочу использовать в Unity (C#), поэтому я скомпилировал dll C++ и создал для него dll-оболочку C#. Я сделал это с помощью SWIG.

Когда я делаю это:

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

Это нормально, и я попробовал Debug.Log(k), чтобы проверить возвращаемое значение k, и, похоже, оно работает правильно. Поэтому я думаю, что я могу вызывать функции и получать возвращаемые значения.

Но когда я пытаюсь это сделать, Unity падает:

g.AddNode(num_of_nodes);

Кажется, он будет падать каждый раз, когда я пытаюсь отправить значения. Не знаю, почему это происходит.


Класс, который я хочу обернуть, это библиотека 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;
}

person ZaneArn    schedule 28.12.2011    source источник


Ответы (1)


Возможно, это не тот ответ, который вы ищете, но лучшее, что я могу придумать на основе вопроса.

Я бы начал с более простого примера и пошел дальше. Например, начните с изменения вашей функции, чтобы она ничего не делала, кроме возврата, например:

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.

person eselk    schedule 11.03.2014