首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在C#中使用指针偏移

在C#中使用指针偏移
EN

Stack Overflow用户
提问于 2011-04-23 01:17:29
回答 3查看 1.6K关注 0票数 3

我一直在开发一个应用程序,它使用API从Windows事件日志中获取事件。目前我被指针偏移量所困。我使用的特定结构是EVENTLOGRECORD (参见:http://msdn.microsoft.com/en-us/library/aa363646(v=vs.85).aspx。我的C#结构定义为:

代码语言:javascript
复制
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto, Pack = 1)]
internal struct EVENTLOGRECORD
{
    internal UInt32 Length;
    internal UInt32 Reserved;
    internal UInt32 RecordNumber;
    internal UInt32 TimeGenerated;
    internal UInt32 TimeWritten;
    internal UInt32 EventID;
    internal UInt16 EventType;
    internal UInt16 NumStrings;
    internal UInt16 EventCategory;
    internal UInt16 ReservedFlags;
    internal UInt32 ClosingRecordNumber;
    internal UInt32 StringOffset;
    internal UInt32 UserSidLength;
    internal UInt32 UserSidOffset;
    internal UInt32 DataLength;
    internal UInt32 DataOffset;
}

我的ReadEventLog函数声明为:

代码语言:javascript
复制
[DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Auto, EntryPoint = "ReadEventLog")]
internal static extern Boolean ReadEventLog(IntPtr hEventLog, EVT_READ_FLAGS dwReadFlags, UInt32 dwRecordOffset, IntPtr lpBuffer, UInt32 nNumberOfBytesToRead, out UInt32 pnBytesRead, out UInt32 pnMinNumberOfBytesNeeded);

我可以用数据填充这个结构,并且可以通过使用IntPtr.Add访问SourceName和ComputerName部分。示例:

代码语言:javascript
复制
IntPtr pSrc = IntPtr.Add(pRecord, Marshal.SizeOf(typeof(EVENTLOGRECORD)));
string sSrc = Marshal.PtrToStringAuto(pSrc);
Console.WriteLine("source: {0}\n", sSrc);

IntPtr pComp = IntPtr.Add(pSrc, (sSrc.Length * 2) + 2);
string sComp = Marshal.PtrToStringAuto(pComp);
Console.WriteLine("computer: {0}\n", sComp);

我的问题是尝试从结构中获取字符串部分。我似乎找不出正确的偏移量是什么。我可以在C++中实现,但我似乎不能在C#中实现。下面是我在C++中使用的代码片段(elr是(EVENTLOGRECORD*)pRecord):

代码语言:javascript
复制
char* strings = (LPSTR)((LPBYTE) elr + elr->StringOffset);
while (elr->NumStrings)
{
    wprintf(L"String: %s\n", strings);
    strings += (wcslen((wchar_t*)strings) * sizeof(wchar_t)) + sizeof(wchar_t);
    elr->NumStrings--;
}

希望有人能帮我解释一下我错过了什么。我也很好奇是否有任何替代IntPtr.Add的方法,因为它需要.NET 4.0。我无论如何都不是p/invoke方面的专家。谢谢。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2011-04-26 21:19:24

经过一段时间的编程来清理大脑,我终于有了一个解决方案。我错误地将偏移量设置得太大,因为我获取了结构的大小(EVENTLOGRECORD),将其添加到StringOffset,然后将其添加到现有对象。我真正需要做的就是将偏移量添加到现有的IntPtr (pRecord)。不知道为什么之前没有点击。

所以简单地这样做:

代码语言:javascript
复制
int offset = ((int)(((EVENTLOGRECORD)o).StringOffset));
IntPtr pStrings = IntPtr.Add(pRecord, offset);
string sString = Marshal.PtrToStringAuto(pStrings);
Console.WriteLine("string : {0}\n", sString);

足够的..is来获取字符串。不过还是要谢谢你的助攻。显然,我缺乏将建议标记为有帮助的代表。我想我只是需要离开这段时间。

票数 1
EN

Stack Overflow用户

发布于 2011-04-23 01:34:35

如果您使用Marshal.PtrToStructure()将数据块的第一部分复制到一个EVENTLOGRECORD,那么您应该能够执行如下操作:

代码语言:javascript
复制
EVENTLOGRECORD record;
... Copy the ptr into record ...
IntPtr pStrings = IntPtr.Add(pRecord, (record.StringOffset * 2));

我很乐意为您做这件事,但是我太懒了,没有时间去做所有其他的p/invoke部分,这些p/invoke部分只能进行ReadEventLog调用。

票数 1
EN

Stack Overflow用户

发布于 2011-04-23 01:38:13

现在问可能为时已晚。为什么不使用.NET的System.Diagnostics.EventLog类?据我所知,您对EventLog类有问题。你有没有尝试过EventLogReader类,它适用于Windows版本的Vista和更高版本?

使用Reflector,您还可以了解它们是如何进行编组的。看起来不可能让编组器完成全部工作。它们确实将数据读取到一个简单的字节数组中,并将其存储在EventLogEntry类中,该类直接从字节数组中读取所需的数据。

来读取它们在EventLogEntry类中执行的替换字符串。databuf成员是来自本机ReadEventLog调用的字节数组。

代码语言:javascript
复制
[MonitoringDescription("LogEntryReplacementStrings")]
public string[] ReplacementStrings
{
    get
    {
        string[] strArray = new string[this.ShortFrom(this.dataBuf, this.bufOffset + 0x1a)];
        int index = 0;
        int offset = this.bufOffset + this.IntFrom(this.dataBuf, this.bufOffset + 0x24);
        StringBuilder builder = new StringBuilder();
        while (index < strArray.Length)
        {
            char ch = this.CharFrom(this.dataBuf, offset);
            if (ch != '\0')
            {
                builder.Append(ch);
            }
            else
            {
                strArray[index] = builder.ToString();
                index++;
                builder = new StringBuilder();
            }
            offset += 2;
        }
        return strArray;
    }
}

你的,阿洛伊斯·克劳斯

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/5758049

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档