C# C-修改IntPtr指向的内容(替换字符串)

C# C-修改IntPtr指向的内容(替换字符串),c#,C#,代码: IntPtr buff buff可以指向相当大的东西。这个buff将包含一个字符串,比如XYZ123,我想用ABC456替换它。不幸的是,数据的其余部分不是字符串。这使我无法执行以下操作: …警察局长PtrToStringAnsibuff //这里要换线吗 …StringToHGlobalAnsi元帅 因为它会破坏其他非字符串二进制数据。考虑到大尺寸和我无法进行上述转换,最好的方法是什么 执行封送处理。复制到循环中的字节[],查找字符序列 谢谢 我不确定我是否完全理解你的意图。 但是

代码:

IntPtr buff

buff可以指向相当大的东西。这个buff将包含一个字符串,比如XYZ123,我想用ABC456替换它。不幸的是,数据的其余部分不是字符串。这使我无法执行以下操作:

…警察局长PtrToStringAnsibuff

//这里要换线吗

…StringToHGlobalAnsi元帅

因为它会破坏其他非字符串二进制数据。考虑到大尺寸和我无法进行上述转换,最好的方法是什么

执行封送处理。复制到循环中的字节[],查找字符序列


谢谢

我不确定我是否完全理解你的意图。 但是,既然您不想弄乱非托管缓冲区,为什么不替换非托管缓冲区本身中的字符串,而不将其转换为托管字符串并返回呢

只要字符串由“\0”标准C字符串分隔,就可以查找要替换的字符串,例如XYZ123。您可以自己使用指针算法逐字符遍历字符串,甚至可以P/invoke

LPTSTR StrStr(          
LPCTSTR lpFirst,
    LPCTSTR lpSrch
);
从shlwapi.dll

找到字符串XYZ123的指针后,可以使用以下方法替换它:

LPTSTR StrCpy(
    LPTSTR psz1,
    LPCTSTR psz2
);
或者,你自己去实现它

注:上述功能有安全的替代方案。见:

下面的示例演示如何使用不安全代码和IntPtr。这可能有助于:

public unsafe static void Main()
{
    int a = 10;
    Console.WriteLine("a is {0} ({0:X})", a);
    IntPtr ip = new IntPtr(&a);
    byte* pTarget = (byte*)ip.ToPointer() + 1;
    *pTarget = 2;

    Console.WriteLine("a is {0} ({0:X})", a);
}

编辑:我假设两个字符串的长度相同。因为它们在您的示例中

考虑到您的字节数组很大,我不会一直复制它。 在我看来,你要么

编写一个C函数并在C代码中调用它 编写一个比较和交换函数作为不安全的C代码,类似于dtroy中的示例。 这是一些未经测试的代码,您可以尝试:

static unsafe Boolean Compare(byte* src, byte * compare, int size)
{
    Boolean result = true;
    int i = 0;
    while (result && i < size)
    {
        result=result&&*(src+i)==*(compare+i);
    }
    return result;
}

static unsafe void Replace (byte* src, byte* newData, int size) {
    for (int i = 0; i < size; i++)
        *(src + i) = *(newData + i);   
}

static unsafe Boolean Swap(IntPtr ptr, byte[] search, byte[] newData, int ptrBytes)
{
    Boolean result = false;
    byte* pSearch =  (byte*) Marshal.UnsafeAddrOfPinnedArrayElement(search, 0);
    byte* pReplace = (byte*)Marshal.UnsafeAddrOfPinnedArrayElement(newData, 0);
    for (int i = 0; i < ptrBytes - search.Length;i++ )
    {
        byte* pTarget = (byte*)ptr.ToPointer()+i;
        if (Compare(pTarget, pSearch, search.Length))
        {
            Replace(pTarget, pReplace, newData.Length);
            return true;
        }
    }
    return result;
}