在 C++/CLI 中访问托管 class 成员数组变量
Access managed class member array variable in C++/CLI
由于 P/Invoke 不支持返回动态大小的数组(您必须在编译时静态指定数组的大小),我决定在 . net 应用程序,否则用 C# 编写。
从IpHlpApi.dll中获取GetTcpTable2函数...
我使 C# classes 匹配该函数中的类型,如下所示:
public class MibTcpTable2
{
public int NumEntries;
public MibTcpRow2[] Table;
}
public class MibTcpRow2
{
public int State;
public int LocalAddr;
public int LocalPort;
public int RemoteAddr;
public int RemotePort;
public int OwningPid;
public int OffloadState;
}
在我的 C++/CLI 程序中,我调用 GetTcpTable2,如 MSDN 示例中所示,然后遍历生成的数组并将其输出分配给 Tcp[=28= 的新实例]2 class 我用 C# 制作。
见代码:
PMIB_TCPTABLE2 pTcpTable;
ULONG ulSize = 0;
DWORD dwRetVal = 0;
pTcpTable = (MIB_TCPTABLE2 *)MALLOC(sizeof(MIB_TCPTABLE2));
if (pTcpTable == NULL) {
return nullptr;
}
ulSize = sizeof(MIB_TCPTABLE);
if ((dwRetVal = ::GetTcpTable2(pTcpTable, &ulSize, TRUE)) == ERROR_INSUFFICIENT_BUFFER)
{
FREE(pTcpTable);
pTcpTable = (MIB_TCPTABLE2 *)MALLOC(ulSize);
if (pTcpTable == NULL) {
return nullptr;
}
}
NetClasses::MibTcpTable2^ managedTable = gcnew NetClasses::MibTcpTable2();
managedTable->Table = gcnew cli::array<NetClasses::MibTcpRow2^>(pTcpTable->dwNumEntries);
if ((dwRetVal = ::GetTcpTable2(pTcpTable, &ulSize, TRUE)) == NO_ERROR)
{
for (int i = 0; i < pTcpTable->dwNumEntries; i++)
{
managedTable->Table[i].LocalAddr = pTcpTable->table[i].dwLocalAddr;
managedTable->Table[i].LocalPort = pTcpTable->table[i].dwLocalPort;
managedTable->Table[i].OffloadState = pTcpTable->table[i].dwOffloadState;
managedTable->Table[i].OwningPid = pTcpTable->table[i].dwOwningPid;
managedTable->Table[i].RemoteAddr = pTcpTable->table[i].dwRemoteAddr;
managedTable->Table[i].RemotePort = pTcpTable->table[i].dwRemotePort;
managedTable->Table[i].State = pTcpTable->table[i].dwState;
}
}
然而,Visual Studio 2015 讨厌在 for 循环中访问 managedTable。它抱怨 "expression must have a class type." 好的,所以这通常意味着您使用了错误的数据访问器运算符,所以我尝试了一个点。没有骰子。
我到底如何访问 managedTable 的 Table 成员?在 for 循环之前对其的访问是有效的。为什么它在 for 循环中无效?
您的数组访问为您提供了托管对象的句柄,因此您的字段访问不应该也是 -> 而不是 . ?
数组[i]->字段
由于 P/Invoke 不支持返回动态大小的数组(您必须在编译时静态指定数组的大小),我决定在 . net 应用程序,否则用 C# 编写。
从IpHlpApi.dll中获取GetTcpTable2函数... 我使 C# classes 匹配该函数中的类型,如下所示:
public class MibTcpTable2
{
public int NumEntries;
public MibTcpRow2[] Table;
}
public class MibTcpRow2
{
public int State;
public int LocalAddr;
public int LocalPort;
public int RemoteAddr;
public int RemotePort;
public int OwningPid;
public int OffloadState;
}
在我的 C++/CLI 程序中,我调用 GetTcpTable2,如 MSDN 示例中所示,然后遍历生成的数组并将其输出分配给 Tcp[=28= 的新实例]2 class 我用 C# 制作。 见代码:
PMIB_TCPTABLE2 pTcpTable;
ULONG ulSize = 0;
DWORD dwRetVal = 0;
pTcpTable = (MIB_TCPTABLE2 *)MALLOC(sizeof(MIB_TCPTABLE2));
if (pTcpTable == NULL) {
return nullptr;
}
ulSize = sizeof(MIB_TCPTABLE);
if ((dwRetVal = ::GetTcpTable2(pTcpTable, &ulSize, TRUE)) == ERROR_INSUFFICIENT_BUFFER)
{
FREE(pTcpTable);
pTcpTable = (MIB_TCPTABLE2 *)MALLOC(ulSize);
if (pTcpTable == NULL) {
return nullptr;
}
}
NetClasses::MibTcpTable2^ managedTable = gcnew NetClasses::MibTcpTable2();
managedTable->Table = gcnew cli::array<NetClasses::MibTcpRow2^>(pTcpTable->dwNumEntries);
if ((dwRetVal = ::GetTcpTable2(pTcpTable, &ulSize, TRUE)) == NO_ERROR)
{
for (int i = 0; i < pTcpTable->dwNumEntries; i++)
{
managedTable->Table[i].LocalAddr = pTcpTable->table[i].dwLocalAddr;
managedTable->Table[i].LocalPort = pTcpTable->table[i].dwLocalPort;
managedTable->Table[i].OffloadState = pTcpTable->table[i].dwOffloadState;
managedTable->Table[i].OwningPid = pTcpTable->table[i].dwOwningPid;
managedTable->Table[i].RemoteAddr = pTcpTable->table[i].dwRemoteAddr;
managedTable->Table[i].RemotePort = pTcpTable->table[i].dwRemotePort;
managedTable->Table[i].State = pTcpTable->table[i].dwState;
}
}
然而,Visual Studio 2015 讨厌在 for 循环中访问 managedTable。它抱怨 "expression must have a class type." 好的,所以这通常意味着您使用了错误的数据访问器运算符,所以我尝试了一个点。没有骰子。
我到底如何访问 managedTable 的 Table 成员?在 for 循环之前对其的访问是有效的。为什么它在 for 循环中无效?
您的数组访问为您提供了托管对象的句柄,因此您的字段访问不应该也是 -> 而不是 . ?
数组[i]->字段