我已经映射了C++函数(来自WLanapi.dll):
DWORD WINAPI WlanHostedNetworkQueryStatus(
_In_ HANDLE hClientHandle,
_Out_ PWLAN_HOSTED_NETWORK_STATUS *ppWlanHostedNetworkStatus,
_Reserved_ PVOID pvReserved
);到以下C#代码:
[DllImport("Wlanapi.dll", SetLastError = true)]
static extern UInt32 WlanHostedNetworkQueryStatus(
[In] IntPtr hClientHandle,
[Out] out _WLAN_HOSTED_NETWORK_STATUS ppWlanHostedNetworkStatus,
[In, Out] IntPtr pvReserved
);我还映射了所需的所有结构和枚举以及其他东西(例如,获取clientHandle指针和启动托管网络)。
_WLAN_HOSTED_NETWORK_STATUS的映射如下:
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct _WLAN_HOSTED_NETWORK_STATUS
{
public _WLAN_HOSTED_NETWORK_STATE HostedNetworkState;
public Guid IPDeviceID;
public _DOT11_MAC_ADDRESS wlanHostedNetworkBSSID;
public _DOT11_PHY_TYPE dot11PhyType;
public UInt32 ulChannelFrequency;
public UInt32 dwNumberOfPeers;
public _WLAN_HOSTED_NETWORK_PEER_STATE[] PeerList;
}现在,在执行该函数时,我不知道如何正确地使用ppWlanHostedNetworkStatus等等。函数返回ERROR_SUCCESS (0),这意味着我已经正确地调用并传递了参数:
_WLAN_HOSTED_NETWORK_STATUS netStatus = new _WLAN_HOSTED_NETWORK_STATUS();
WlanHostedNetworkQueryStatus(clientHandle, out netStatus, IntPtr.Zero);但是,在查询ppWlanHostedNetworkStatus的值(比如网络的状态或连接的对等点的数量)时,我只得到了一些奇怪的长整数(我可以说是内存地址,但我不确定),例如:
netStatus.HostedNetworkState.ToString();返回
11465720
HostedNetworkState是定义如下的枚举:
public enum _WLAN_HOSTED_NETWORK_STATE
{
wlan_hosted_network_unavailable,
wlan_hosted_network_idle,
wlan_hosted_network_active
}所以.toString()应该从枚举返回其中一个字符串,对吗?
我很确定这与指针等有关,因为在_WLAN_HOSTED_NETWORK_STATUS ( MS文档 )的文档中,它说在调用该函数之前,ppWlanHostedNetworkStatus应该是NULL,并且它本身就是指向结构的指针.
我如何调试它?我正在用C#编码,VS 2012.
谢谢你的帮助。
-编辑-编辑
我进一步尝试用IntPtr映射函数作为参数,传递IntPtr.Zero和Marshal.PtrToStruct,但是当我试图这样做的时候,会得到AccessViolationException .
[DllImport("Wlanapi.dll", SetLastError = true)]
static extern UInt32 WlanHostedNetworkQueryStatus(
[In] IntPtr hClientHandle,
[Out] out IntPtr ppWlanHostedNetworkStatus,
[In, Out] IntPtr pvReserved
);然后:
IntPtr ppStatus = IntPtr.Zero;
WlanHostedNetworkQueryStatus(clientHandle, out ppStatus, IntPtr.Zero);
_WLAN_HOSTED_NETWORK_STATUS netStatus = (_WLAN_HOSTED_NETWORK_STATUS)Marshal.PtrToStructure(ppStatus, typeof(_WLAN_HOSTED_NETWORK_STATUS));编辑2
按照Fermat2357的建议,我取消了要映射的结构体的注释部分,并将以下内容更改为计数指向指针的指针:
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct _WLAN_HOSTED_NETWORK_STATUS
{
public _WLAN_HOSTED_NETWORK_STATE HostedNetworkState;
public Guid IPDeviceID;
public _DOT11_MAC_ADDRESS wlanHostedNetworkBSSID;
public _DOT11_PHY_TYPE dot11PhyType;
public UInt32 ulChannelFrequency;
public UInt32 dwNumberOfPeers;
//public _WLAN_HOSTED_NETWORK_PEER_STATE[] PeerList;
}我这样叫它:
IntPtr ppStatus = IntPtr.Zero;
WlanHostedNetworkQueryStatus(clientHandle, out ppStatus, IntPtr.Zero);
IntPtr ppStatus2 = new IntPtr(ppStatus.ToInt32());
_WLAN_HOSTED_NETWORK_STATUS stat = (_WLAN_HOSTED_NETWORK_STATUS)Marshal.PtrToStructure(ppStatus2, typeof(_WLAN_HOSTED_NETWORK_STATUS));
netStatus = stat.HostedNetworkState.ToString();这最终给出了正确的网络状态(启动后激活).现在我得想办法整理那个动态数组..。
到目前为止谢谢您的帮助Fermat2357
发布于 2012-12-10 17:06:02
编辑:我要尝试的一件事是我用来帮助调试的技巧--用字节数组替换您的结构,并查看您拉回的内容(好的,在本例中是uint数组):
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct _WLAN_HOSTED_NETWORK_STATUS
{
[MarshalAs(UnmanagedType.ByValArray, ArraySubType=UnmanagedType.U4, SizeConst = 48)]
public uint[] scratch;
}但是,当我在本地运行这个值时,我得到了非常奇怪的值--第一个(10x4) =40个字节被归零:
0 0 0 0
0 0 0 0
0 0 4D454D4C 28
16DCD870 0 787F6447 80000020
...omitted...尝试这组P/Invoke声明:
(在LINQPad中完成,因此相应地替换"Dump“方法)
void Main()
{
IntPtr clientHandle;
int negotiatedVersion;
if(WlanOpenHandle(2, IntPtr.Zero, out negotiatedVersion, out clientHandle) != 0)
{
throw new InvalidOperationException("Could not open handle");
}
Console.WriteLine("Negotiated version:{0}", negotiatedVersion);
IntPtr pNetStatus = IntPtr.Zero;
if(WlanHostedNetworkQueryStatus(clientHandle, out pNetStatus, IntPtr.Zero) != 0)
{
throw new InvalidOperationException("Could not query network status");
}
var netStatus = (WLAN_HOSTED_NETWORK_STATUS)Marshal.PtrToStructure(pNetStatus, typeof(WLAN_HOSTED_NETWORK_STATUS));
Console.WriteLine(netStatus.PeerList[0]);
WlanFreeMemory(pNetStatus);
WlanCloseHandle(clientHandle, IntPtr.Zero);
}
[DllImport("Wlanapi.dll", SetLastError = true)]
[return:MarshalAs(UnmanagedType.Bool)]
public static extern bool WlanOpenHandle(
[In] int dwClientVersion,
IntPtr pReserved,
[Out] out int pdwNegotiatedVersion,
[Out] out IntPtr phClientHandle
);
[DllImport("Wlanapi.dll", SetLastError = true)]
[return:MarshalAs(UnmanagedType.Bool)]
public static extern bool WlanCloseHandle(
[In] IntPtr hClientHandle,
IntPtr pReserved
);
[DllImport("Wlanapi.dll", SetLastError = true)]
static extern UInt32 WlanHostedNetworkQueryStatus(
[In] IntPtr hClientHandle,
[Out] out IntPtr ppWlanHostedNetworkStatus,
[In, Out] IntPtr pvReserved
);
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct _WLAN_HOSTED_NETWORK_STATUS
{
public _WLAN_HOSTED_NETWORK_STATE HostedNetworkState;
public Guid IPDeviceID;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst=6)]
public string wlanHostedNetworkBSSID;
public _DOT11_PHY_TYPE dot11PhyType;
public UInt32 ulChannelFrequency;
public UInt32 dwNumberOfPeers;
public IntPtr PeerList;
}
public enum _WLAN_HOSTED_NETWORK_STATE
{
wlan_hosted_network_unavailable,
wlan_hosted_network_idle,
wlan_hosted_network_active
}
public enum _DOT11_PHY_TYPE : uint
{
dot11_phy_type_unknown = 0,
dot11_phy_type_any = 0,
dot11_phy_type_fhss = 1,
dot11_phy_type_dsss = 2,
dot11_phy_type_irbaseband = 3,
dot11_phy_type_ofdm = 4,
dot11_phy_type_hrdsss = 5,
dot11_phy_type_erp = 6,
dot11_phy_type_ht = 7,
dot11_phy_type_IHV_start = 0x80000000,
dot11_phy_type_IHV_end = 0xffffffff
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct _WLAN_HOSTED_NETWORK_PEER_STATE
{
[MarshalAs(UnmanagedType.ByValTStr, SizeConst=6)]
public string PeerMacAddress;
_WLAN_HOSTED_NETWORK_PEER_AUTH_STATE PeerAuthState;
}
public enum _WLAN_HOSTED_NETWORK_PEER_AUTH_STATE
{
wlan_hosted_network_peer_state_invalid,
wlan_hosted_network_peer_state_authenticated
}https://stackoverflow.com/questions/13803265
复制相似问题