Как вызвать 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 это будет то же самое).
- не используйте AnyCPU в качестве платформы, предпочитайте использовать платформу x64 или x86, соответственно, в DLL Cygwin.
- по какой-то причине я еще не понял, почему, вызывая
sprintf
, sscanf
, stringstream
... и отпечатывает консольные методы из dll, заставляя программу остановиться.
Теперь что вы можете сделать:
- Убедитесь, что папка bin cygwin добавлена в путь или скопирует ваши DLL-зависимости в папку DLL (зависимости обычно: Cygwin1.dll, cyggcc_s-seh-1.dll cygstdС++ - 6.dll. Используйте инструмент Dependency Walker для проверки).
- Просто убедитесь, что: добавьте макрос EXPORT_API, используйте его для каждого экспортируемого метода. лайк:
#define EXPORT_API extern "C" __cdecl __declspec(dllexport)
- Ваш образец DLL очень прост, скомпилируйте свой код с помощью консоли Cygwin:
g++ -c library.cpp; g++ -o cygcallFromCsharp.dll library.o
g++ -c library.cpp; g++ -o cygcallFromCsharp.dll library.o
- Я использовал из С# следующее (отладка работающего каталога установлена в расположение dll):
DllImport(@"cygcallFromCsharp.dll", CallingConvention=CallingConvention.Cdecl)] static extern int Test();
Надеюсь, это поможет.