如何从.NET Core调用cygwin编译的C++

How to call cygwin compiled C++ from .NET Core?

本文关键字:cygwin 编译 C++ 调用 Core NET      更新时间:2023-10-16

我正在尝试做类似的事情:

我在Windows上工作,但我的意图是让我的代码稍后也能在Linux上工作(因此我使用cygwin和clion进行C++)。VS2017使用普通的C#编译器为.NET Core应用程序编译C#。我的问题是在visual studio中得到这个错误:

"程序'[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++代码。cpp:

#include <cstdint>
extern "C" __declspec(dllexport) int32_t Test(){
return 10;
}

这是clion 生成的我的cmake调用

C:\Users\Daant.CLion2018.1\system\cygwin_cmake\bin\cmake.exe--构建/cygdrive/c/Users/Daant/CLionProjects/callFromCsharp/cmake构建版本--目标调用FromCsharp---j 6

这是我的C#代码:

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++方法。

让我们从不该做什么开始

当从C#加载Cygwin dll时(我想从Visual studio加载时也是一样的)。

  1. 不使用AnyCPU作为平台,更喜欢使用x64或x86平台,分别在Cygwin dll中
  2. 出于某种原因,我还不知道为什么,调用sprintfsscanfstringstream。。。并从dll打印到控制台的方法导致程序停止

现在你能做什么:

  1. 请确保将cygwin-bin文件夹添加到路径中,或将DLL的依赖项复制到DLL的文件夹中(依赖项通常为:Cygwin1.DLL、cyggcc_s-seh-1.DLL cygstdc++-6.DLL。使用依赖项沃克工具进行检查)
  2. 只是为了确保:添加EXPORT_API宏,在每个导出的方法上使用它。比如:

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

  1. 您的DLL示例非常简单,使用Cygwin控制台编译代码:g++ -c library.cpp; g++ -o cygcallFromCsharp.dll library.o
  2. 我从C#中使用了以下内容(调试运行目录设置为dll位置):

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

希望它能有所帮助。

我实现了一个与cygwin兼容的dotnet加载程序。你可以在这里找到它:https://github.com/smx-smx/EzDotnet

为了能够使用.NET中的Cygwin(没有任何崩溃),入口点必须是一个Cygwin应用程序,在Cygwin下编译和链接。

我添加了一个cygwin示例,演示了使用p/Invoke以及read(2)write(2)将C#stdin/stdout重定向到cygwin(否则它将不可见)

/samples/cli/ezdotnet.exe。/CoreCLR/cygcoreclrhost.dll。/samples/Managed/Cygwin/bin/Debug/net5.0/Cygwin.dll ManagedSample.EntryPoint Entry