2010-11-25 44 views
0

以下代碼在從C#調用時起作用,但效率不高,因爲我從受管理的世界獲取數據 ,創建本地本機副本,調用Win32函數,然後將 數據複製回託管參數,返回給調用者。C++/CLI將跟蹤句柄轉換爲Win32的本地指針?

有沒有辦法完成以下工作?

1)將blinttable UInt32引用參數直接傳遞給Win32調用?請注意0​​這個Win32調用更新值,我想返回給調用者(即theSerialNumber)在本質上,我可以pin_ptr UInt32參考參數(即theSerialNumber)LPDWORD本地函數可以使用並直接更新其值?

2)將StringBuilder緩衝區直接傳遞給本地函數?我想我會 需要設置StringBuilder.Capacity = MAX_PATH + 1;但是,我不知道如何pin_ptr到 其內部緩衝區,本地函數將使用和更新。

我一直在這些問題上試驗,搜索和敲打我的頭幾個小時,所以 我真的很感謝你的幫助!

感謝,

邁克


void MCVolume::VolumeInformation(String^ theRootPathName, 
      StringBuilder^% theVolumeName, 
      UInt32% theSerialNumber, 
      UInt32% theMaxComponentLength, 
      MEFileSystemFeature% theFileFlags, 
      StringBuilder^% theFileSystemName) 
{ 

pin_ptr<const wchar_t> rootPathName = PtrToStringChars(theRootPathName); 

wchar_t volumeName[MAX_PATH+1]; 
memset(volumeName, 0x0, MAX_PATH+1); 
wchar_t fileSystemName[MAX_PATH+1]; 
memset(fileSystemName, 0x0, MAX_PATH+1); 
DWORD serialNumber = 0; 
DWORD fileFlags = 0; 
DWORD maxComponentLength = 0; 

//pin_ptr<DWORD> serialNumber = &theSerialNumber; 

if (GetVolumeInformationW(rootPathName, 
      volumeName, 
      MAX_PATH+1, 
      &serialNumber, 
      &maxComponentLength, 
      &fileFlags, 
      fileSystemName, 
      MAX_PATH+1) == false)         
{ 
    // Handle error 
    throw gcnew Exception("GetVolumeInformationW failed."); 
} 

// Send back results... 
theVolumeName = gcnew StringBuilder(marshal_as<String^>(volumeName)); 
theSerialNumber = serialNumber; 
theMaxComponentLength = maxComponentLength; 
theFileFlags = (MEFileSystemFeature) fileFlags; 
theFileSystemName = gcnew StringBuilder(marshal_as<String^>(fileSystemName)); 

回答

0

因爲這兩個字符串類型(託管字符串和本地WCHAR *)的你無法擺脫編組的兩種方式是根本不同的。此外,GC需要跟蹤已分配的受管理資源,這就是爲什麼您總是需要構建一個要發送回受管理世界的對象。

+0

不正確,*您*不必構造要發送回託管世界的對象。使用P/Invoke並讓編譯器爲您完成工作。 – 2010-11-25 11:23:05

0

只需使用來自C++/CLI的P/Invoke。有關更多信息,請參閱here