在c#中使用来自c源代码的cygwin编译的dll,在socket()、fork()和类似对象上出现读写保护内存错误

在c#中使用来自c源代码的cygwin编译的dll,在socket()、fork()和类似对象上出现读写保护内存错误,c#,c,sockets,dll,cygwin,C#,C,Sockets,Dll,Cygwin,我有一个用C编写的源代码,它使用了大量套接字发送器和侦听器调用,然后是几个操作函数。套接字是多播的,也是单播的 很多读写操作都发生在它上面。我使用cygwin编译了它,生成了一个exe,它在所有windows变体上都运行良好。同时,当我从同一个dll生成了一个dll,并试图通过DLLimport在C#中使用它时,它工作正常,直到达到下面的行 if((sendFd = socket(AF_INET,SOCK_DGRAM,0)) < 0) 如果没有所有的套接字或fork(),它可以很好地执行

我有一个用C编写的源代码,它使用了大量套接字发送器和侦听器调用,然后是几个操作函数。套接字是多播的,也是单播的

很多读写操作都发生在它上面。我使用cygwin编译了它,生成了一个exe,它在所有windows变体上都运行良好。同时,当我从同一个dll生成了一个dll,并试图通过DLLimport在C#中使用它时,它工作正常,直到达到下面的行

if((sendFd = socket(AF_INET,SOCK_DGRAM,0)) < 0)

如果没有所有的套接字或fork(),它可以很好地执行基本操作,如字符串操作等。

如果我理解正确,那么您正在尝试
[DllImport]
在.NET程序集中使用Cygwin编译的本机库

好吧,这就是灾难的秘诀:

您正试图在同一应用程序中使用两个不同的C运行时库。Cygwin提供了它自己的各种系统功能的实现,它不仅仅是相应Windows API的包装器。这里有几件事可能会出错:

  • 可执行文件包含一些在调用
    main()
    之前运行的初始化和启动代码。此代码由编译器自动生成并初始化C运行时。通过P/调用DLL可以绕过该代码
  • Cygwin使用自己的套接字代码,需要进行一些低级的系统调用才能与网卡交互——由于Cygwin使用自己的实现,所以它在Windows运行时的后台执行此操作
  • 如果要在.NET应用程序中使用的本机DLL中使用套接字,则需要使用Winsocks并使用Microsoft的编译器进行编译,以便它与本机Windows库相链接


    例如,您可以使用Visual Studio 2012 Express for Desktop来实现此功能。

    我实现了一个与cygwin兼容的dotnet加载程序。 你可以在这里找到它:

    为了能够从.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条目


    这可能有很多原因,你的问题根本无助于缩小范围。这就是.NET程序员使用System.NET.Socket类的原因。请告诉我,您没有试图在
    C
    /
    .NET
    中使用的
    dll
    中使用
    fork()
    -这条路径会导致疯狂。我没有在该dll中使用fork(),但我不能创建套接字。,请注意,这不是一件简单的事情,你可以在.NET中轻松完成,这是一个用C语言实现的协议,我不能再在.NET中重写它了。。重写对你来说好吗。。。数千行。
    Attempt to read write protected memory, or other memory is corrupt.