W jaki sposób należy zadeklarować tę strukturę C dla interopu?
Muszę użyć starszej procedury C w aplikacji, którą tworzę. Kod tutaj działa, ale muszę przekonwertować prawie wszystkie pola na tablice char w celu użycia. Czy jest lepszy sposób, aby to zrobić? Próbowałem niektórych wersji używając ciągów, wszystko bezskutecznie.
To jest kod znaleziony w oryginalnym pliku nagłówkowym ...
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;
... i to jest deklaracja, której używam w mojej aplikacji 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;
}
Czy jest lepszy sposób na zrobienie tego?
EDYTOWAĆ:Opierając się na odpowiedzi Justina Rudda, przetestowałem tę wersję struktury:
[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 ... */
}
Próbowałem go z powodzeniem tylko w niektórych polach, ale zmieniłem to wszystko, pojawiają się problemy z wartościami zwracanymi. Na przykład wysyłam to ...
pxucamrv3.xumrpgmservidorc08 = "PHAPREXW";
pxucamrv3.xumrversaopgmsrvc02 = "01";
pxucamrv3.xumrpgmclientec08 = "PHAOCLXN";
pxucamrv3.xumrversaopgmclientec02 = "02";
pxucamrv3.xumridservidorc30 = "N006";
pxucamrv3.xumrcodfalhac05 = "00000";
pxucamrv3.xumrretcomc02 = "00";
pxucamrv3.xumrretusuc02 = "00";
... i weź to ...
pxucamrv3.xumrpgmservidorc08 == "PHAPREX"
pxucamrv3.xumrversaopgmsrvc02 == "0"
pxucamrv3.xumrpgmclientec08 == "PHAOCLX"
pxucamrv3.xumrversaopgmclientec02 == "0"
pxucamrv3.xumridservidorc30 == "N006"
pxucamrv3.xumrcodfalhac05 == "01 "
pxucamrv3.xumrretcomc02 == "W"
pxucamrv3.xumrretusuc02 == "0"
... jak widzimy, istnieje problem z ustawianiem / unarsowaniem ciągów. Pola znaków wyglądają dobrze. Nie jest to problem z mapowaniem, ponieważ początek pól ciągów jest w porządku. Ale wydaje się, że obcina koniec strun. A moje wywołanie testowe nie powinno zwracać błędu (przy użyciu poprzedniej struktury, działa), więc procedura C nie otrzymała danych tak jak powinna (powinna zwracać tylko zera wxumrretcomc02; zwrócone „W” oznacza, że wystąpił błąd, ale istnieje wiele kodów błędów rozpoczynających się od „W”).
Będę się w to wkopywał.
Ponownie przepraszam za mój słaby angielski. :)