Как вызвать cygwin, скомпилированный C++ из.NET Core?

Я пытаюсь сделать что-то похожее на это:

Я работаю над Windows, но я хочу, чтобы мой код работал на Linux слишком поздно (поэтому я работаю с cygwin и клионом для C++). VS2017 для компиляции С# для приложения.NET Core с обычным компилятором С#. Моя проблема заключается в получении этой ошибки в визуальной студии:

"Программа" [19944] dotnet.exe "вышла с кодом -1073741819 (0xc0000005)" Нарушение доступа ".

Вот мой файл cmake (сгенерированный с помощью clion):

cmake_minimum_required(VERSION 3.10) project(callFromCsharp)

set(CMAKE_CXX_STANDARD 14)

add_library(callFromCsharp SHARED library.cpp)

Вот мой C++ код в library.cpp:

#include <cstdint>

extern "C" __declspec(dllexport) int32_t Test(){
    return 10;
}

Это мой призыв к тэку, созданный клионом

C:\Users\Daant.CLion2018.1\system\cygwin_cmake\bin\cmake.exe --build/cygdrive/c/Пользователи /Daant/CLionProjects/callFromCsharp/cmake-build-release --target callFromCsharp - -j 6

Вот мой код С#:

    class Program
    {
        [DllImport("cygcallFromCsharp.dll", EntryPoint = "Test", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
        public static extern Int32 Test();

        [STAThread]
        static void Main()
        {
            var res = Test();
            Console.WriteLine($"Done! {res}");
            Console.ReadLine();
        }
    }

Как это решить? Я просто хочу вызвать метод C++ без ошибок или исключений.

Ответы

Ответ 1

Давайте начнем с того, что не делать

при загрузке Cygwin dll из С# (я думаю, из Visual Studio это будет то же самое).

  1. не используйте AnyCPU в качестве платформы, предпочитайте использовать платформу x64 или x86, соответственно, в DLL Cygwin.
  2. по какой-то причине я еще не понял, почему, вызывая sprintf, sscanf, stringstream... и отпечатывает консольные методы из dll, заставляя программу остановиться.

Теперь что вы можете сделать:

  1. Убедитесь, что папка bin cygwin добавлена в путь или скопирует ваши DLL-зависимости в папку DLL (зависимости обычно: Cygwin1.dll, cyggcc_s-seh-1.dll cygstdС++ - 6.dll. Используйте инструмент Dependency Walker для проверки).
  2. Просто убедитесь, что: добавьте макрос EXPORT_API, используйте его для каждого экспортируемого метода. лайк:

#define EXPORT_API extern "C" __cdecl __declspec(dllexport)

  1. Ваш образец DLL очень прост, скомпилируйте свой код с помощью консоли Cygwin: g++ -c library.cpp; g++ -o cygcallFromCsharp.dll library.o g++ -c library.cpp; g++ -o cygcallFromCsharp.dll library.o
  2. Я использовал из С# следующее (отладка работающего каталога установлена в расположение dll):

DllImport(@"cygcallFromCsharp.dll", CallingConvention=CallingConvention.Cdecl)] static extern int Test();

Надеюсь, это поможет.