c# - 从 C# 调用 Cygwin 的 Seg 错误
问题描述
我有一些最初为 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 构建的版本中删除的,我希望不要,但可能包含错误。
推荐阅读
- javascript - 如何对对象的元素执行映射功能?
- node.js - Nodejs请求响应未定义
- regex - 正则表达式在一个包含另一个字符串时查找两个字符串之一
- c# - '指数数组的边界之外。' 当通过 List.count 将 Index 设置为 0 时?
- java - 无法在 Swagger 上看到根 API 端点
- python - TypeError:将形状转换为 TensorShape 时出错:int() 参数必须是字符串、类似字节的对象或数字,而不是“元组”。在蟒蛇
- c++ - 将 C++ 整数类型模板参数转换为“更长”的整数类型
- html - 尽管 CSS 设置为显示,但类仍显示:无
- flutter - 向下滚动时隐藏底部导航栏,反之亦然
- python - pandas 通过非 nan 值之前和之后填充 nans