I have to use a legacy C routine in the application I am developing. The code in here works, but I have to convert almost all the fields to char arrays in order to use it. There is a better way to do it? I have tried some version using strings, all to no avail.
This is the code found in the original header file...
typedef struct PXUCAMR
{
char xumrversaocomc01;
char xumrretcomc02[2];
char xumrretusuc02[2];
char xumrcodfalhac05[5];
char xumrfiller1c01;
char xumrtipoambclic01;
char xumrambientec01;
char xumrconvertec01;
char xumroperacaoc01;
char xumropcaoexec01;
xumrcom_t *xumrhandleconnb31;
char xumrreshconnc04[4];
long xumrtamdadosb31;
char xumrtransacaosrvc08[8];
char xumrtransrvdb2c04[4];
char xumrpgmservidorc08[8];
char xumrversaopgmsrvc02[2];
char xumrconectardbc01;
char xumrusuariosrvc08[8];
char xumrsenhasrvc08[8];
char xumridcriptc08[8];
char xumrpgmclientec08[8];
char xumrversaopgmclientec02[2];
char xumridclientec20[20];
char xumrtipoidclientec01;
char xumrusuarioclientec08[8];
char xumrprodutophac16[16];
char xumridservidorc30[30];
char xumrdadosc10000[10000];
}
pxucamr_t;
... and this is the declaration I am using in my C# app...
[StructLayout(LayoutKind.Sequential)]
internal struct PXUCAMR
{
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)]
public char[] xumrversaocomc01;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
public char[] xumrretcomc02;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
public char[] xumrretusuc02;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 5)]
public char[] xumrcodfalhac05;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)]
public char[] xumrfiller1c01;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)]
public char[] xumrtipoambclic01;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)]
public char[] xumrambientec01;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)]
public char[] xumrconvertec01;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)]
public char[] xumroperacaoc01;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)] // 16
public char[] xumropcaoexec01;
[MarshalAs(UnmanagedType.I4)]
public int xumrhandleconnb31;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
public char[] xumrreshconnc04;
[MarshalAs(UnmanagedType.I4)]
public int xumrtamdadosb31;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)] // 36
public char[] xumrtransacaosrvc08;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
public char[] xumrtransrvdb2c04;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
public char[] xumrpgmservidorc08;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
public char[] xumrversaopgmsrvc02;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)]
public char[] xumrconectardbc01;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)] // 67
public char[] xumrusuariosrvc08;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
public char[] xumrsenhasrvc08;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
public char[] xumridcriptc08;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
public char[] xumrpgmclientec08;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)] // 93
public char[] xumrversaopgmclientec02;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)]
public char[] xumridclientec20;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)] // 114
public char[] xumrtipoidclientec01;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
public char[] xumrusuarioclientec08;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)] // 138
public char[] xumrprodutophac16;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 30)] // 168
public char[] xumridservidorc30;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 10000)]
public char[] xumrdadosc10000;
}
Is there a better way of doing it?
EDIT:
Based in Justin Rudd's answer, I have tested this version of the struct:
[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Ansi)]
internal struct PXUCAMRV3
{
public char xumrversaocomc01;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 2)]
public string xumrretcomc02;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 2)]
public string xumrretusuc02;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 5)]
public string xumrcodfalhac05;
public char xumrfiller1c01;
public char xumrtipoambclic01;
public char xumrambientec01;
public char xumrconvertec01;
public char xumroperacaoc01;
public char xumropcaoexec01; // 16
[MarshalAs(UnmanagedType.I4)]
public int xumrhandleconnb31;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 4)]
public string xumrreshconnc04;
[MarshalAs(UnmanagedType.I4)]
public int xumrtamdadosb31;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 8)] // 36
public string xumrtransacaosrvc08;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 4)]
public string xumrtransrvdb2c04;
/* ... same pattern to remaining fields ... */
}
I have tried it in just some fields with success, but I changed all of it, problems with the returning values appear. For example, I send this...
pxucamrv3.xumrpgmservidorc08 = "PHAPREXW";
pxucamrv3.xumrversaopgmsrvc02 = "01";
pxucamrv3.xumrpgmclientec08 = "PHAOCLXN";
pxucamrv3.xumrversaopgmclientec02 = "02";
pxucamrv3.xumridservidorc30 = "N006";
pxucamrv3.xumrcodfalhac05 = "00000";
pxucamrv3.xumrretcomc02 = "00";
pxucamrv3.xumrretusuc02 = "00";
... and get this ...
pxucamrv3.xumrpgmservidorc08 == "PHAPREX"
pxucamrv3.xumrversaopgmsrvc02 == "0"
pxucamrv3.xumrpgmclientec08 == "PHAOCLX"
pxucamrv3.xumrversaopgmclientec02 == "0"
pxucamrv3.xumridservidorc30 == "N006"
pxucamrv3.xumrcodfalhac05 == "01 "
pxucamrv3.xumrretcomc02 == "W"
pxucamrv3.xumrretusuc02 == "0"
... as we can see, there is a problem with the marshalling/unmarshalling of strings. The char fields are looking alright. It's not a mapping problem, as the beggining of the string fields are ok. But it seems to be truncating the end of the strings. And my test call should not return an error (using the previous struct, it works), so the C routine didn't receive the data as it should too (should return only zeros in xumrretcomc02; the returned "W" means there is an error, but I there are lots of error codes starting in "W").
I will keep digging into it.
Again, sorry for my poor english. :)