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