quiero llamar a la DhcpGetClientInfo API de C#, pero tengo una pregunta sobre la conversión de esta estructura C a C#:Convertir C Unión a C# (alineadas de forma incorrecta)
typedef struct _DHCP_CLIENT_SEARCH_INFO {
DHCP_SEARCH_INFO_TYPE SearchType;
union {
DHCP_IP_ADDRESS ClientIpAddress;
DHCP_CLIENT_UID ClientHardwareAddress;
LPWSTR ClientName;
} SearchInfo;
} DHCP_SEARCH_INFO, *LPDHCP_SEARCH_INFO;
creo que la conversión correcta es la siguiente:
[StructLayout(LayoutKind.Explicit, Size=12)]
public struct DHCP_SEARCH_INFO
{
[FieldOffset(0)]
public DHCP_SEARCH_INFO_TYPE SearchType;
[FieldOffset(4)]
public DHCP_IP_ADDRESS ClientIpAddress;
[FieldOffset(4)]
public DHCP_BINARY_DATA ClientHardwareAddress;
[FieldOffset(4), MarshalAs(UnmanagedType.LPWStr)]
public string ClientName;
};
Pero eso da una System.TypeLoadException: información adicional: no se pudo cargar el tipo 'Dhcpsapi.DHCP_SEARCH_INFO' del ensamblado 'ConsoleApplication3, Version = 1.0.0.0, Culture = neutral, PublicKeyToken = null', ya que contiene una campo de objeto en el desplazamiento 4 que es incorrectamente aligne d o superpuesto por un campo no objeto.
Esta es la conversión de los otros tipos en caso de que quiera compilar:
public enum DHCP_SEARCH_INFO_TYPE : uint
{
DhcpClientIpAddress = 0,
DhcpClientHardwareAddress = 1,
DhcpClientName = 2
};
[StructLayout(LayoutKind.Sequential)]
public struct DHCP_BINARY_DATA
{
public uint DataLength;
public IntPtr Data;
};
[StructLayout(LayoutKind.Sequential)]
public struct DHCP_IP_ADDRESS
{
public UInt32 IPAddress;
}
EDIT:
verifiqué sizeof y las compensaciones en C:
#pragma comment(lib,"Dhcpsapi.lib")
int _tmain(int argc, _TCHAR* argv[])
{
DHCP_SEARCH_INFO si;
printf("sizeof(DHCP_SEARCH_INFO)=%d\n", sizeof(DHCP_SEARCH_INFO));
printf("ClientIpAddress offset=%d\n", (PBYTE)&si.SearchInfo.ClientIpAddress - (PBYTE)&si);
printf("ClientHardwareAddress offset=%d\n", (PBYTE)&si.SearchInfo.ClientHardwareAddress - (PBYTE)&si);
printf("ClientName offset=%d\n", (PBYTE)&si.SearchInfo.ClientName - (PBYTE)&si);
return 0;
}
salida es:
sizeof(DHCP_SEARCH_INFO)=12
ClientIpAddress offset=4
ClientHardwareAddress offset=4
ClientName offset=4
EDITAR: Según la respuesta de Camford, declare la estructura como a continuación. Usar sizeof también debería ser correcto para x64.
[StructLayout(LayoutKind.Explicit, Size=12)]
public struct DHCP_SEARCH_INFO
{
[FieldOffset(0)]
public DHCP_SEARCH_INFO_TYPE SearchType;
[FieldOffset(sizeof(DHCP_SEARCH_INFO_TYPE))]
public DHCP_IP_ADDRESS ClientIpAddress;
[FieldOffset(sizeof(DHCP_SEARCH_INFO_TYPE))]
public IntPtr ClientName;
[FieldOffset(sizeof(DHCP_SEARCH_INFO_TYPE))]
public DHCP_BINARY_DATA ClientHardwareAddress;
};
¿Ha intentado 'static_assert (sizeof (DHCP_SEARCH_INFO) == 12," No me sorprende que no funcione. ");'? – Lundin
@Lundin: registré C: sizeof (DHCP_SEARCH_INFO) == 12, por eso agregué el tamaño = 12 – Remko
clase pública DHCP_IP_ADDRESS ¿Estás seguro de que no querías decir struct? – Camford