Проблемы с переносом C ++ DLL из C # - PullRequest
0 голосов
/ 28 декабря 2011

Я использую System.Runtime.InteropServices для вызова нескольких функций, написанных на C ++, из моего приложения на C #.У меня просто проблемы с конкретной функцией, которая возвращает массив.

Я видел, что моя функция не должна ничего возвращать, и указатель на «возвращаемую переменную» должен быть en entry.Но я не могу сделать это правильно.

Например, если у меня есть функция в c ++

void func(double *y, double *x){...}

, которая манипулирует массивом x и возвращает массив y.

Я делаю:

- в моем .h:

extern "C" __declspec(dllexport) void func(double *y,double *x);

- в моем .cpp:

__declspec(dllexport) void func(double *y,double *x){...}

- в моем коде c #:

static class AnyClass
  {
    [DllImport(dllPath)]
    public extern static void func(out double[] y, double[] x);

    int otherfunc
    {
      double[] x = new double[5];
      double[] y = new double[5];

      ...

      func(out y, x); 
    }
  }

, но это дает мне исключение System.EntryPointNotFoundException.

Любая подсказка?

Ответы [ 3 ]

3 голосов
/ 28 декабря 2011

EntryPointNotFoundException означает, что в вашей DLL не найдено ничего с именем 'function'.

В вашем файле .h вы называете его 'func'.Но в вашем .cpp файле вы называете это «функцией».И поскольку ваш файл .h - единственное место, которое объявляет extern "C", то, что фактически происходит, - это то, что функция экспортируется вашей DLL c ++ - style-name-mangled, а не plain-c-style.Поэтому, когда C # ищет «функцию» в стиле обычного c, он не может ее найти.

1 голос
/ 28 декабря 2011

EntryPointNotFoundException означает, что во время выполнения не удалось найти указанное имя функции в вашей DLL.

Возможные причины:

  • Вы неправильно написали имя функции в вашей DLL или в вашейprogram
  • Вы не деактивировали искажение имени (extern "C")

Первую причину легко найти, просто перепроверьте все имена и убедитесь, что они действительно равны.Если по какой-либо причине вы не можете изменить DLL, но, как и другое имя, отличное от C #, вы можете использовать свойство DllImportAttribute.EntryPoint , чтобы указывать на функцию с другим именем.

Второй труднее найти.Чтобы диагностировать проблему, я предлагаю вам использовать Dependency Walker , чтобы увидеть, что на самом деле происходит внутри вашей скомпилированной DLL.Используя этот инструмент, вы можете увидеть имена функций, а также, являются ли они C ++ или нет.

Вы уже пытались использовать extern "C", чтобы удостовериться, что имя функции не влияет на искажение имени.Возможно, вы не включили файл .h из своего файла .cpp, чтобы компилятор вообще не видел extern "C".

1 голос
/ 28 декабря 2011

Я думаю, вы также должны указать extern "C" в вашем .cpp файле. Если нет, то вы можете получить две разные функции func, одна из которых с правильной связью будет только объявлена ​​и не определена.

Примечание: Afair связь extern "C" также указывает, как называются функции в файле DLL. Для функций C ++ некоторые пред. Постфиксы добавляются к имени, относящемуся к подписи (то есть к параметрам и типу возвращаемого значения). Это необходимо, потому что вы можете перегружать функции в C ++. Поэтому, если вы не укажете extern "C", функции будут именоваться по-разному в DLL и, следовательно, не будут найдены управляемым кодом.

...