【问题标题】:Native winAPI in C++\CLIC++\CLI 中的本机 winAPI
【发布时间】:2011-04-15 22:50:26
【问题描述】:

我开始了一个具有 Windows 窗体应用程序类型的新项目,我放置了两个文本框(文本框 1 和文本框 2)和一个按钮。我使用 OpenFileDialog 从系统中选择一个文件并将其路径放在 textbox1 中,我为按钮输入了以下代码:

HANDLE hFile;
HANDLE hMap ;
LPVOID base;

hFile = ::CreateFile((LPCWSTR)Marshal::StringToHGlobalAnsi(this->textBox1->Text).ToPointer(), GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE,0,OPEN_EXISTING , FILE_FLAG_SEQUENTIAL_SCAN, 0);

unsigned long sifi= ::GetFileSize(hFile,NULL);

if(hFile !=INVALID_HANDLE_VALUE){
hMap= ::CreateFileMapping(hFile, 0, PAGE_READONLY | SEC_COMMIT, 0, 0, 0);//create Mem mapping for the file in virtual memory
 }
if( hMap!=NULL){
base = ::MapViewOfFile(hMap, FILE_MAP_READ, 0, 0, 0);//load the mapped file into the RAM
                            }
this->textBox2->Text=sifi.ToString();

我试图用该代码做的是从 textbox1 读取文件路径以使用它来打开文件句柄,然后获取文件的大小并将其放入 textbox2。现在的问题是,textbox2 显示的文件大小值不正确。所有文件似乎总是 4294967295!

编辑:

谢谢大家,我已经解决了这个问题。在CreateFile的第一个参数中,应该是:

(LPCWSTR)Marshal::StringToHGlobalUni(this->textBox1->Text).ToPointer()

【问题讨论】:

  • 对 .net 4.0 中引入的内存映射文件使用 .net 类不是更容易吗?
  • 是的,但我已经在 .net 4.0 之前写过了,顺便说一句,如果我使用 .net 类会比原生 api 更快吗?
  • 获得工作代码会更快! ;-) 我希望性能差别不大。
  • @DavidHeffernan:嗨,实际上在性能上有很大的不同:在我的机器上,使用托管的内存映射文件类比使用本机 API 慢 31 倍!我使用 C++/CLI 以及指向映射视图的不安全 C# 指针测量了这一点,它们都一样快。
  • 只是对未来读者的警告,问题断言“它应该是”的代码有内存泄漏并且没有类型安全。我强烈建议使用PtrToStringChars 作为我的答案,而不是Marshal 类来访问文件名。

标签: .net winapi visual-c++ c++-cli


【解决方案1】:

建议使用GetFileSizeEx 而不是GetFileSize。但是想想你的CreateFile 调用失败了。

CreateFile 不接受 HGLOBAL。而且您将字符串转换为 ANSI,然后将其传递给CreateFile 的 Unicode 版本,这也被破坏了。

只要保持 Unicode,就像这样:

pin_ptr<wchar_t> wszFilename = PtrToStringChars(textBox1->Text);
HANDLE hFile = ::CreateFileW(wszFilename, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE,0,OPEN_EXISTING , FILE_FLAG_SEQUENTIAL_SCAN, 0);
if (hFile == 0 || hFile == INVALID_HANDLE_VALUE) throw gcnew Win32Exception();

【讨论】:

    【解决方案2】:

    GetFileSize 函数正在返回一个错误值。

    注意,如果返回值为 INVALID_FILE_SIZE (0xffffffff),一个 应用程序必须调用 GetLastError 来 判断函数是否有 成功或失败。

    请参阅API docs on MSDN

    顺便说一句,我认为@David Heffernan 有一个观点。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-06-19
      • 2016-03-16
      • 1970-01-01
      • 2011-05-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多