Я должен использовать устаревшую подпрограмму C в приложении, которое я разрабатываю. Код здесь работает, но я должен преобразовать почти все поля в массивы символов, чтобы использовать его. Есть лучший способ сделать это? Я попробовал какую-то версию, используя строки, но все безрезультатно.
Это код, найденный в исходном заголовочном файле ...
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;
... и это объявление, которое я использую в своем приложении C # ...
[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;
}
Есть ли лучший способ сделать это?
EDIT:
Основываясь на ответе Джастина Радда, я проверил эту версию структуры:
[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 ... */
}
Я попробовал это только в некоторых полях с успехом, но я изменил все это, проблемы с возвращаемыми значениями появляются. Например, я отправляю это ...
pxucamrv3.xumrpgmservidorc08 = "PHAPREXW";
pxucamrv3.xumrversaopgmsrvc02 = "01";
pxucamrv3.xumrpgmclientec08 = "PHAOCLXN";
pxucamrv3.xumrversaopgmclientec02 = "02";
pxucamrv3.xumridservidorc30 = "N006";
pxucamrv3.xumrcodfalhac05 = "00000";
pxucamrv3.xumrretcomc02 = "00";
pxucamrv3.xumrretusuc02 = "00";
... и получите это ...
pxucamrv3.xumrpgmservidorc08 == "PHAPREX"
pxucamrv3.xumrversaopgmsrvc02 == "0"
pxucamrv3.xumrpgmclientec08 == "PHAOCLX"
pxucamrv3.xumrversaopgmclientec02 == "0"
pxucamrv3.xumridservidorc30 == "N006"
pxucamrv3.xumrcodfalhac05 == "01 "
pxucamrv3.xumrretcomc02 == "W"
pxucamrv3.xumrretusuc02 == "0"
... как мы видим, существует проблема с сортировкой / отменой сортировки строк. Поля символов выглядят хорошо. Это не проблема отображения, так как начало строковых полей в порядке. Но это похоже на обрезание конца строки. И мой тестовый вызов не должен возвращать ошибку (используя предыдущую структуру, она работает), поэтому подпрограмма C не получила данные так, как должна (должна возвращать только нули в xumrretcomc02 ; возвращенный " W "означает, что есть ошибка, но есть много кодов ошибок, начинающихся с" W ").
Я буду продолжать копаться в этом.
Опять же, извините за мой плохой английский. :)