由於P/Invoke不支持返回動態大小的數組(您必須在編譯時靜態指定數組大小),所以我決定爲某些C++/CLI包裝器編寫一些函數,我需要在.net應用程序中,否則用C#編寫。在C++/CLI中訪問託管類成員數組變量
採取GetTcpTable2功能從IPHLPAPI.DLL ... 我做了C#類,以匹配該函數的類型如下:
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示例,然後遍歷結果數組並將其輸出分配給我在C#中創建的TcpTable2類的新實例。 見代碼:
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年恨訪問裏面的managedTable for循環。它抱怨說「表達式必須有類的類型」。好吧,這通常意味着你使用了錯誤的數據訪問器操作符,所以我嘗試了一個點。沒有骰子。
我該如何訪問managedTable的表成員?在for循環之前訪問它是有效的。爲什麼它在for循環內沒有效?
你可能要考慮使用'System.Net.IPEndPoint'而不是兩個'int',對於每一個地址/端口對 –
不是一個壞主意。感謝您的建議。 – dodexahedron
小心避免太多的幫助,.NET IPGlobalProperties.GetActiveTcpConnections()和GetActiveTcpListeners()方法已經可以做到這一點。 –