【发布时间】:2010-12-12 07:19:09
【问题描述】:
[DllImport("kernel32.dll", SetLastError=true)]
public static extern unsafe bool WriteFile(IntPtr hFile, void* lpBuffer, uint nNumberOfBytesToWrite, out uint lpNumberOfBytesWritten, IntPtr lpOverlapped);
我正在通过带有签名的 Write(..) 方法来实现这一点:
Write(IntPtr handleFile, void* bufferData, uint length){
void* buffer = bufferData
while (length > 0)
{
uint wrtn;
if (!WriteFile(handle, buffer, len, out wrtn, IntPtr.Zero))
{
// Do some error handling
}
// THIS DOESNT WORK!
// I want to move along the buffer to be able to write its remainder...
// I tried many variations of this as well, but it seems even '+' is not valid for a void*
buffer += wrtn;
len -= wrtn;
}
}
正如我通过查看 this (the use of the read counterpart is discussed) 了解到的,我需要在我的代码中实现一个 while 循环,因为缓冲区的写入/读取可能不会一次性完成。这就是问题的开始:
如果我想保留我的 C# 方法签名以接受 void*,这与链接读取示例不同,其中字节* 被接受为缓冲区的参数。
这意味着在 WriteFile 一次通过后,我应该将我的 void* 移动到尚未写入的缓冲区的开头。我显然不能通过仅使用包含写入字节数的 uint 来增加 void* 来做到这一点......我知道 void* 没有预定的大小,因此增加是不可能的,但我想知道我应该如何实现我正在努力。
【问题讨论】:
-
当您可以使用 System.IO 命名空间提供的内容时,您还有什么理由使用 Win32 api 不安全代码?
-
是的,扩展了我对本地内容/互操作的了解,并了解了 .net 通常对我们隐藏的内容。我从来没有被教过我所谓的“基本”东西(指针,...),我非常想学习。
-
@Kris:如果你想了解指针和低级的东西,我会使用低级语言(C、C++、(QT、wxWidgets)),而不是尝试学习高级到低级语言。
-
..除非他想了解 .net 上下文中的指针和内存管理内部结构。我认为这样的练习很有用,即使只是为了指出为什么你不应该在生产代码中做这样的事情。
-
你可能不想在生产代码中做这件事,但我不喜欢 .NET 的一些事情:省略最新的文件打开/保存对话框,例如IFileDialog 公开的只是一个例子。尝试在您的高级语言项目中获得类似的东西(高级语言适用于您可能想做的 99.9% 的事情)需要了解此类内容......
标签: c# winapi void-pointers pointer-arithmetic