【问题标题】:How do you iterate through a uint64* with size_t, and what is the equivilent for c#?您如何使用 size_t 遍历 uint64*,c# 的等价物是什么?
【发布时间】:2015-11-28 15:54:36
【问题描述】:

我正在开发一个用 c#(使用 this base)编写的 Teamspeak3 插件,并且正在获取频道列表,这是在 c 中的操作方法:

/* Print list of all channels on this server */
    char* s;
    char msg[1024];
    anyID myID;
    uint64* ids;
    size_t i;
    unsigned int error;

    if(ts3Functions.getChannelList(serverConnectionHandlerID, &ids) != ERROR_ok) {
        ts3Functions.logMessage("Error getting channel list", LogLevel_ERROR, "Plugin", serverConnectionHandlerID);
        return;
    }
    printf("PLUGIN: Available channels:\n");
    for(i=0; ids[i]; i++) {
        /* Query channel name */
        if(ts3Functions.getChannelVariableAsString(serverConnectionHandlerID, ids[i], CHANNEL_NAME, &s) != ERROR_ok) {
            ts3Functions.logMessage("Error querying channel name", LogLevel_ERROR, "Plugin", serverConnectionHandlerID);
            return;
        }
        printf("PLUGIN: Channel ID = %llu, name = %s\n", (long long unsigned int)ids[i], s);
        ts3Functions.freeMemory(s);
    }
    ts3Functions.freeMemory(ids);  /* Release array */

for(i=0; ids[i]; i++),它声明uint64* 正在与size_t 进行迭代。

我想知道如何迭代它,以及 c# 中最接近的等价物是什么?

【问题讨论】:

  • 您是否考虑过检查现有问题(如果有帮助)(在 C# 中等效于 size_t),例如 Correct way to marshal SIZE_T*? 简短回答:“使用 IntPtr 和/或 UIntPtr 做得很好——这些类型是专门为此目的而存在的!..."
  • 我看过那条评论,但我也在问如何使用 size_t 进行迭代,以及是否有办法在 c# 中做同样的事情。因为在示例中,我不知道这样做会产生什么影响。
  • 根据我自己的测试,迭代 size_t 类似于迭代 int,除了变量定义为 size_t 而不是 int 和循环中的比较也应该使用size_t 类型的变量来完成。仅作为说明,可以将类型转换为 int ;即(int)my_size_t 但是,这是不可取的——当不需要强制转换时,将每种类型都视为正确的类型。 For Q 关于如何在 C# 中进行操作。 C#: Retrieving and using an IntPtr* through reflection 有帮助吗?
  • 对不活动感到抱歉,无论如何,我在 c++ 中做了等价的操作。我发现this 返回了this。仍在试图弄清楚为什么会这样。

标签: c# c++ pointers size-t teamspeak


【解决方案1】:

我找到了答案(感谢 localhost 和 Chris 发现这个问题!)。基本上,ulong* 指向一个数组,size_t 正在通过它,试图找到通道的 ID。因为在 C++ 中,在一个 for 循环中,除了零之外的每个数字都是真的,它一直在查询它,直到没有更多的通道 id,并返回一个零。 The TeamSpeak Community Forums Post

对于任何对 C# 代码感兴趣的人,请使用 this plugin

if (funcs.getChannelList(serverConnectionHandlerID, ref v) != Errors.ERROR_ok) {
    funcs.logMessage("Failed", LogLevel.LogLevel_ERROR, "Plugin", serverConnectionHandlerID);
    break;
}
// Convert it to a ulong*
ulong * ptr = (ulong * ) v.ToPointer();
// Iterate through the array
for (ulong t = 0; ptr[t] != 0; t++) {
    // The String result
    string result;
    // The pointer result
    IntPtr res = IntPtr.Zero;
    /*
     Channel Variable Arguments:
    1: The server connection ID
    2: The iterated channel id
    3: An IntPtr at 0, which signifies CHANNEL_NAME
    4: A reference to stores results
    */
    if (
    funcs.getChannelVariableAsString(serverConnectionHandlerID, ptr[t], new IntPtr(0), ref res) != Errors.ERROR_ok) {
        // Error message
        funcs.logMessage("Error", LogLevel.LogLevel_WARNING, "Plugin", serverConnectionHandlerID);
        break;
    }
    // Convert the pointer to a string
    if ((result = Marshal.PtrToStringAnsi(res)) == null) break;
    // Print it
    funcs.printMessageToCurrentTab(result);
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-08-23
    • 2015-07-10
    • 2014-05-08
    • 1970-01-01
    • 1970-01-01
    • 2011-01-19
    • 2010-12-07
    • 2010-12-01
    相关资源
    最近更新 更多