簡體   English   中英

在 c# 中使用來自 c 源的 cygwin 編譯的 dll,錯誤在 socket()、fork() 和類似的讀寫保護內存

[英]Using cygwin compiled dll from c source in c#, error read write protected memory on socket() , fork() and similar

我有一個用 C 編寫的源代碼,它使用了很多套接字發送器和偵聽器調用,然后是幾個操作函數。 套接字是多播的,也是單播的。

大量的讀寫操作發生在它上面。 我使用 cygwin 編譯它,生成一個 exe,它在所有 Windows 變體上運行良好。 同時,當我從中生成一個 dll 並嘗試通過 DLLimport 在 C# 中使用它時,它工作正常,直到到達以下行

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

Visual Studio 報錯:

Attempt to read write protected memory, or other memory is corrupt.

沒有所有套接字的東西或 fork() 它可以很好地執行基本操作,例如字符串操作等。

如果我理解正確,那么您是在嘗試[DllImport]一個在 .NET 程序集中使用 Cygwin 編譯的本機庫?

好吧,這是災難的根源:

您正試圖在同一個應用程序中使用兩個不同的 C 運行時庫。 Cygwin 提供了它自己的各種系統功能的實現,它不僅僅是相應 Windows API 的包裝器。 這里有幾件事情可能會出錯:

  1. 可執行文件包含一些在調用main()之前運行的初始化和啟動代碼。 此代碼由編譯器自動生成並初始化 C 運行時。 您可以通過 P/調用您的 DLL 來繞過該代碼。
  2. Cygwin 使用自己的套接字代碼,它需要進行一些低級系統調用才能與網卡進行交互 - 由於 Cygwin 使用自己的實現,因此它在 Windows 運行時背后執行此操作。

如果您想在 .NET 應用程序中使用的本機 DLL 中使用套接字,則需要使用 Winsocks 並使用 Microsoft 的編譯器對其進行編譯,因此它會鏈接到本機 Windows 庫。

例如,您可以為此使用 Visual Studio 2012 Express for Desktop。

我實現了一個與 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 條目

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM