VB.NET 2008或更高版本:通过winapi读取STDIN时内存冲突

VB.NET 2008或更高版本:通过winapi读取STDIN时内存冲突,vb.net,winapi,stdout,stdin,kernel32,Vb.net,Winapi,Stdout,Stdin,Kernel32,我正在尝试将VB6应用程序移植到VB.NET。 这是一个控制台应用程序,它从STDIN读取数据,修改数据并将其写入STDOUT 谷歌是我的朋友,所以我现在花了好几天时间寻找解决方案。 这个搜索为我提供了几个版本的WinApi ReadFile,我都试过了。 我还尝试了几个版本的.NET。 然而……在我尝试过的每一种组合中,我都会不断出现内存冲突错误。 根据im使用的ReadFile变量,错误略有不同,但它们都是相似的 例如,请参见此错误变体: makeDataFilter < Test.i

我正在尝试将VB6应用程序移植到VB.NET。 这是一个控制台应用程序,它从STDIN读取数据,修改数据并将其写入STDOUT

谷歌是我的朋友,所以我现在花了好几天时间寻找解决方案。 这个搜索为我提供了几个版本的WinApi ReadFile,我都试过了。 我还尝试了几个版本的.NET。 然而……在我尝试过的每一种组合中,我都会不断出现内存冲突错误。 根据im使用的ReadFile变量,错误略有不同,但它们都是相似的

例如,请参见此错误变体:

makeDataFilter < Test.in > Test.Out

Unhandled Exception: System.AccessViolationException: Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
   at makeDataFilter.Filter_IO.ReadFile(Int64 hFile, String& lpBuffer, Int64 nNumberOfBytesToRead, Int64 lpNumberOfBytesRead, String& lpOverlapped)
   at makeDataFilter.Filter_IO.GetData() in C:\Projects\.NET 2019\makeDataFilter\Filter_IO.vb:line 229
   at makeDataFilter.Filter_IO.Main() in C:\Projects\.NET 2019\makeDataFilter\Filter_IO.vb:line 118
   
   
以下是产生上述错误的ReadFile API调用的变体:

<DllImport("kernel32")>
Declare Function ReadFile(
    ByVal hFile As Long,
    lpBuffer As String,
    nNumberOfBytesToRead As Long,
    lpNumberOfBytesRead As Long,
    lpOverlapped As String
) As String
我在代码中使用它的方式如下:

Sub GetData()
    Dim sBuff As String         
    Dim lBytesRead As Long      
    Dim rc As Long              
                                
    lContentLength = 256        
    sBuff = lContentLength      
    Do
        rc = ReadFile(hStdIn, sBuff, lContentLength, lBytesRead, 0&)
        sFilterData &= Left$(sBuff, lBytesRead)
    Loop While rc = 1
End Sub
有人能帮我找到一种在VB.NET中读取标准数据并写入标准数据的有效方法吗?

我想知道

NET Framework提供了一个类,其中包含读取/写入标准输入/输出流的功能。不使用该功能是否有特殊原因

我想您的
GetData
方法可以重写为如下内容:

Sub GetData()
    sFilterData = Console.In.ReadToEnd()
End Sub

但是,“动态”处理输入流数据可能更有效(特别是内存使用),而不是先将整个输入流读取并存储到字符串中,然后开始处理。

System.string是不可变的,因此它决不能作为缓冲区参数的类型出现。改用StringBuilder。为了避免代码中导致AVE的错误,必须在调用之前设置其容量。StringBuilder。。。。。。。请给我一个代码示例。我是一个偶尔的.net程序员:-)@rensduijsense-See。虽然这个例子是为C#编写的,但同样的概念也适用于VB.NET如果您包括使用
控制台.IsInputRedirected
控制台.IsOutputRedirected
来允许程序流控制(如果不重定向)。不管怎么说,答案很好。嗯……有时候事情比人们想象的更简单。:-)正如我提到的,我的代码来自VB6。我不知道这样做的“新”方法。是的,因为这比简单多了。谢谢你的提醒。非常感谢您快速清晰的回答。虽然我想知道这是什么,但我试图在“VB.NET从STDIN读取”中查找信息,但没有出现类似的情况。我只看到Kernel32的几种变体。比如,我用“GetPrivateProfileString”读取ini文件的方式,是的。我懂了。当我个人尝试在谷歌上搜索一些东西时,我也尝试搜索潜在的文档内容,这些内容通常使用常规的英语术语。我只是通过搜索“VB.NET从标准输入流读取”来尝试它,第一个结果是对
控制台.OpenStandardInput
方法的引用。在您的案例中,也许STDIN是一个过于技术化或过于具体的搜索标准……;).NET Framework不直接支持对INI文件的支持。您现在确实可以使用内核函数(
GetPrivateProfileString
)来实现这一点。但是,从长远来看(在迁移应用程序之后),我建议为配置文件切换到另一种文件格式,如XML或JSON。这不仅会使你的应用程序更具可移植性(必要时),还将提供更大的技术配置灵活性。(您可能需要搜索“.NET app.config”或“.NET Core appsettings.json”以了解更多信息。)感谢Bart,两个答案都是如此。非常有用。自VB6发布以来,发生了很多变化:-D
Sub GetData()
    Dim sBuff As String         
    Dim lBytesRead As Long      
    Dim rc As Long              
                                
    lContentLength = 256        
    sBuff = lContentLength      
    Do
        rc = ReadFile(hStdIn, sBuff, lContentLength, lBytesRead, 0&)
        sFilterData &= Left$(sBuff, lBytesRead)
    Loop While rc = 1
End Sub
Sub GetData()
    sFilterData = Console.In.ReadToEnd()
End Sub