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