Мы хотим вызвать функцию C ++ в приложении x64: https://www.inventcom.net/fanuc-focas-library/misc/cnc_diagnoss
Нам нужно передать структуру ODBDGN в функцию.Эта структура содержит объединение, поэтому в c # мы не можем определить объединение, нам нужно сделать следующее:
[StructLayout(LayoutKind.Explicit, Pack=4)]
public class ODBDGN
{
[FieldOffset(0)]
public short datano; /* data number */
[FieldOffset(2)]
public short type; /* axis number */
[FieldOffset(4),
MarshalAs(UnmanagedType.ByValArray, SizeConst = MAX_AXIS)]
public byte[] cdatas;
[FieldOffset(4),
MarshalAs(UnmanagedType.ByValArray, SizeConst = MAX_AXIS)]
public short[] idatas;
[FieldOffset(4),
MarshalAs(UnmanagedType.ByValArray, SizeConst = MAX_AXIS)]
public int[] ldatas;
}
В 32-битном приложении инициализация этой структуры работает нормально.
Int 64-битное приложение, инициализацияэта структура не работает и выдает эту ошибку:
System.TypeLoadException
HResult=0x80131522
Message=Impossible de charger le type 'ODBDGN' à partir de l'assembly 'CommunicationFanuc, Version=2.0.0.0, Culture=neutral, PublicKeyToken=null', car il contient un champ objet à l'offset '4' qui n'est pas correctement aligné ou qui est chevauché par un champ non objet.
Source=CommunicationFanuc
StackTrace:
at CommunicationFanuc.DiagnosticAddress.Read() in D:\Projets\PMM2.0\CommunicationFanuc\Addresses\Channel\Diagnostic\DiagnosticAddress.cs:line 98
at CommunicationFanuc.Tests.PtmFocasEthernet.ReadDiagnostic() in D:\Projets\PMM2.0\CommunicationFanuc.Tests\Ethernet\PtmFocasEthernet.cs:line 809
Я понимаю, что в приложении x64 значение пакета по умолчанию равно 8, поэтому смещение должно быть 8, а не 4:
[StructLayout(LayoutKind.Explicit)]
public class ODBDGN
{
[FieldOffset(0)]
public short datano; /* data number */
[FieldOffset(2)]
public short type; /* axis number */
[FieldOffset(8),
MarshalAs(UnmanagedType.ByValArray, SizeConst = MAX_AXIS)]
public byte[] cdatas;
[FieldOffset(8),
MarshalAs(UnmanagedType.ByValArray, SizeConst = MAX_AXIS)]
public short[] idatas;
[FieldOffset(8),
MarshalAs(UnmanagedType.ByValArray, SizeConst = MAX_AXIS)]
public int[] ldatas;
}
Но еслимы вызываем функцию Cnc_diagnoss C ++, в структуре нам не хватает 2 октета между type
и cdatas
Но когда мы объявляем структуру следующим образом:
[StructLayout(LayoutKind.Sequential)]
public class ODBDGN_Byte
{
public short datano;
public short type;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = MAX_AXIS)]
public byte[] cdatas;
}
это работает(не объединение, но если данные в байтах), и между type
и cdatas
ничего не пропущено. В этом случае datano
смещено, 0 type
равно 2, а cdatas
равносмещение 4
Так почему же мы не можем создать явный макет в этом случае?Я не понимаю, как это работает ...