c# - 从 C# 调用 Cygwin 的 Seg 错误

标签 c# c++ cygwin

我有一些最初为 Linux 编写的 C++ 代码,我可以在 64 位 Windows 下使用 cygwin 下的 gcc 构建和运行它们而不会出现问题。然而,现在我想把它变成一个我可以从 C# 程序调用的 DLL。
我发现我可以让 C# 毫无问题地调用在 cygwin 下编译的 C++ 函数,只要它们不使用 cygwin1.dll 中定义的任何标准 C/C++ 库函数。但是,例如,一旦我执行 printf,整个事情就会以“段错误”退出。
在线搜索答案,我看到它声称您需要先调用 cygwin_dll_init() 。但是,当我添加它时,它只是终止,根本没有错误消息!
我究竟做错了什么?我很确定 .NET 运行时成功地找到了我的 DLL 和 cygwin1.dll,因为如果其中任何一个都不存在,我会得到一个 DllNotFoundException。
这是产生相同症状的最小测试用例。首先,DLL 的 cygwin/C++ 代码:

#include <cstdio>

extern "C" __declspec(dllexport) int test();

int test() {
    printf("Test successful");
    return 14;
}
我用“g++ -o test.dll -shared test.cpp”编译它。
这是调用它的 C# 代码:
using System;
using System.Runtime.InteropServices;

class MainClass {
    [DllImport("cygwin1.dll")]
    private static extern void cygwin_dll_init();
    
    [DllImport("test.dll")]
    private static extern int test();
    
    public static void Main(string[] args) {
        Console.WriteLine("running...");

        // Remove this line if you want a seg fault
        cygwin_dll_init();

        test();

        // Seg fault or no, this never gets run
        Console.WriteLine("done");
    }
}

最佳答案

我强烈建议您使用 mingw64 交叉编译器编译您的 DLL。这允许您构建不使用 cygwin1.dll 的 DLL。相反,它将仅调用 Windows 运行时 DLL。只要您不需要调用任何其他 cygwin DLL,这应该可以正常工作。

  • 您需要使用 cygwin 安装应用程序安装 mingw64 编译器包。安装 mingw64-x86_64-gcc-g++包裹。
  • 创建 GNUmakefile 如下:
  •  # GNUmakefile - for cygwin make will use this instead of Makefile
    
    CXX=x86_64-w64-mingw32-g++
    CXXFLAGS=-Wall -Wextra -Werror
    
    all:    libtest.dll
    
    clean:
        rm -f *.dll
    
    libtest.dll:  test.cpp
        $(CXX) $(CXXFLAGS) -shared -o libtest.dll test.cpp
    
  • 在 cygwin bash 提示符下,运行 make clean all
  • 创建 Makefile 如下:
  • # Makefile - for VS nmake
    
    CS=csc
    CSFLAGS=-nologo -w:3 -warnaserror+ -optimize- -debug+
    
    all :   main.exe
    
    clean :
        del /q *.exe 2> nul:
        del /q *.pdb 2> nul:
    
    main.exe : main.cs
        $(CS) $(CSFLAGS) -t:exe -out:main.exe main.cs
    
  • 在 cmd.exe 提示符下以 nmake -nologo clean all 运行此命令.
  • 运行 exe 为 main.exe .像往常一样,libtest.dll 必须与 main.exe 位于同一目录或路径中。

  • 这里的 makefile 是从使用和不使用 cygwin1.dll 构建的版本中删除的,我希望不要,但可能包含错误。

    关于c# - 从 C# 调用 Cygwin 的 Seg 错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62530574/

    相关文章:

    c# - 绑定(bind)到 WPF 中的设计数据

    c# - 如何在 ASP.NET MVC 中浏览服务器上的文件?

    c++ - 未处理的异常,传递对象?

    c++ - 任意指令指针是否驻留在特定函数中?

    c++ - 用子类定义类数组

    c# - 在roslyn中访问VS完整解决方案

    c# - ASP.NET MVC : How do I handle a view model with many properties?

    linux - 如何使用 linux find 命令清理所有 Maven 项目?

    java - Windows 10 Cygwin 中的 OpenMPI java 绑定(bind)

    cygwin 上的 FFMPEG 无法编译 libx264 错误 : unknown type name ‘HMODULE’