更改IntPtr指向的字符串 [英] Changing the string to which an IntPtr is pointing

查看:119
本文介绍了更改IntPtr指向的字符串的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的C#应用​​程序中,我有一个IntPtr类型的变量lpData(从对非托管代码的调用中接收),它指向一个字符串.

In my C# application I have a variable lpData of type IntPtr (received from a call to unmanaged code), and it points to a string.

我必须将此字符串替换为另一个值.

I have to replace this string with another value.

我尝试过:

int RegQueryValueExW_Hooked(
        IntPtr hKey,
        string lpValueName,
        int lpReserved,
        ref Microsoft.Win32.RegistryValueKind lpType,
        IntPtr lpData,
        ref int lpcbData)
{ 
    lpData = Marshal.StringToHGlobalUni("new string"); 
    ...
}

但这似乎并不能代替实际的字符串.

but this doesn't seem to replace the actual string.

有人可以指出正确的方向吗?

Can someone point me in the right direction on how to do this?

谢谢

推荐答案

当然,它不会替换字符串-您将获得指向调用者具有该值的字符串的指针.您只需替换局部变量"(参数)的值,这不会在调用方改变任何内容.

Of course it doesn't replace the string - you're getting the pointer to the string where your caller has the value. You're only replacing the value of your "local variable" (the parameter), this doesn't change anything on the caller's side.

如果您想修改原始指针上的值(并确保确实要这样做,这就是怪异错误"潜伏的地方-覆盖周围的变量很容易,而忽略空终止符,等等.) ,您可以使用Marshal.Copy,例如:

If you want to modify the value on the original pointer (and make sure you actually do want that, this is where "weird errors" lurk - it's very easy to overwrite surrounding variables, forget about the null terminator, etc.), you can use Marshal.Copy, for example:

var bytes = Encoding.Unicode.GetBytes("your string\0");

Marshal.Copy(bytes, 0, lpData, bytes.Length);

再次-这是非常危险的行为,您不应该这样做.您违反了参数传递等所隐含的若干合同.

Again - this is a very dangerous behaviour and you shouldn't be doing this. You're violating several contracts implied by parameter passing etc.

现在我已经回答了您的问题,让我谈谈您实际需要这样做的错误程度(这与您有关使用StringBuilder的其他帖子非常相关).

Now that I've answered your question, let me talk about how wrong you are about actually needing to do this (and this is very much related to your other post about using the StringBuilder).

您正在尝试修改作为参数传递给您的值.但是,字符串是由调用方分配的.您甚至都不知道它有多长!如果您开始将数据复制到该指针,则将覆盖例如的数据.完全不同的变量,只是在字符串之后随机分配.这被认为是非常糟糕".

You are trying to modify a value passed to you as a parameter. However, the string was allocated by the caller. You don't even know how long it is! If you start copying data to that pointer, you're going to overwrite the data of eg. completely different variables, that just randomly happened to be allocated just after the string. This is considered "very bad".

相反,您要做的是遵循RegQueryValueEx具有的正确过程(

Instead, what you want to do, is follow the proper process that RegQueryValueEx has (http://msdn.microsoft.com/en-us/library/windows/desktop/ms724911(v=vs.85).aspx). That means you first have to check the lpcbData value. If it is large enough to hold all the bytes you want to write, you just write the data to the lpData and set the lpcbData value to the proper length. If not, you still set lpcbData, but return ERROR_MORE_DATA. The caller should then call RegQueryValueEx again, with a larger buffer.

示例代码将如下所示:

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无法保护您,您引起重大问题!

Do note that this is just what I've written after quickly glancing through the documentation - you should investigate further, and make sure you're handling all the possible cases. .NET doesn't protect you in this case, you can cause major issues!

这篇关于更改IntPtr指向的字符串的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆