當然它不會取代字符串 - 你得到的指針到您的調用者有值的字符串。你只是替換你的「局部變量」(參數)的值,這不會改變調用者的任何東西。
如果你想修改原始指針的值(並確保你確實需要這樣做,這就是潛在的「怪異錯誤」的地方 - 覆蓋周圍變量,忘記空終止符等是很容易的。 ),你可以使用Marshal.Copy
,例如:
var bytes = Encoding.Unicode.GetBytes("your string\0");
Marshal.Copy(bytes, 0, lpData, bytes.Length);
再次 - 這是一個非常危險的行爲,你不應該這樣做。您違反由參數隱含幾個路過的合同等
現在,我已經回答了你的問題,讓我說說你即將真正需要做這個(如何錯誤的,這是有很大關係的其他職位關於使用StringBuilder)。
您試圖修改傳遞給您的值作爲參數。但是,該字符串是由調用者分配的。你甚至不知道它是多久!如果您開始將數據複製到該指針,您將覆蓋例如。完全不同的變量,只是偶然發生在字符串後面而已。這被認爲是「非常糟糕」。
相反,您要做的是遵循RegQueryValueEx具有的正確流程(http://msdn.microsoft.com/en-us/library/windows/desktop/ms724911(v=vs.85).aspx)。這意味着您首先必須檢查lpcbData值。如果足夠大以容納要寫入的所有字節,則只需將數據寫入lpData並將lpcbData值設置爲適當的長度即可。如果不是,您仍然設置lpcbData,但返回ERROR_MORE_DATA。調用者應該再次調用RegQueryValueEx,並使用更大的緩衝區。
的示例代碼將是這樣的:
string yourString = "Your string";
int RegQueryValueExW_Hooked(
IntPtr hKey,
string lpValueName,
int lpReserved,
ref Microsoft.Win32.RegistryValueKind lpType,
IntPtr lpData,
ref int lpcbData)
{
var byteCount = Encoding.Unicode.GetByteCount(yourString);
if (byteCount > lpcbData)
{
lpcbData = byteCount;
return ERROR_MORE_DATA;
}
if (lpData == IntPtr.Zero)
{
return ERROR_SUCCESS;
}
lpcbData = byteCount;
var bytes = Encoding.Unicode.GetBytes(yourString);
Marshal.Copy(bytes, 0, lpData, bytes.Length);
return ERROR_SUCCESS;
}
注意,這正是我後,可通過文檔快速掃視寫 - 你應該進一步調查,並確保你正在處理所有可能的情況。 .NET在這種情況下不保護你,你可以引起重大問題!
替換實際的字符串是什麼?你想改變註冊表中的值嗎?字符串是不可變的,所以你只能用一個新引用替換一個字符串。但是,對於那個特定的API調用,您可以使用「StringBuilder」 - 也許這將適用於您想要執行的操作? –
在我的情況下,StringBuilder崩潰(請參閱http:// stackoverflow。com/questions/21722555/easyhook-32-bit-application),所以我嘗試使用IntPtr代替,它不會崩潰;但後來我不知道如何替換字符串。 –
我看到你的其他帖子在這裏:http://stackoverflow.com/questions/21722555/easyhook-32-bit-application ....問題是,它是該API的「調用者」分配緩衝區(和它的大小)並提供指針。由於它不是指向指針/引用參數的指針,因此不能將指針更改回調用方。 –