Diskuze: Převod procedur

C# .NET .NET (C# a Visual Basic) Převod procedur American English version English version

Avatar
hradil11
Člen
Avatar
hradil11:

Ahoj, v práci řeším problém. Dostal sem nový MDB(multi drop bus) na který připojuji zařízení jako čtečku bankovek a pod. Jenže v přiložené dokumentaci je klasická windows dll knihovna na kterou si musím vytvořit metody na přístup k těmto zařízením. V podkladech je dále deklarace procedur a struktur bohužel bud v delphi nebo v c/c++. Takže si vše musím do C# převést. Některé metody fungují ale vyskytl se problém se získáváním informací ze zařízení(typ, verze, apod.). Takže ted řeším kde je chyba a na nic nemůžu přijít, takže kdyby někdo třeba viděl chybu v přepisu tak bych byl rád za radu díky.

Deklarace v delphi:

type BLVInfo = record
{$IFDEF LINUX}
                manufacturer:   Array [0.. 3] of Char;      // manufacturer
{$ENDIF}
                device,                                                                         // device name
                model:                  Array [0..12] of Char;          // model
                version:                Array [0.. 1] of Byte;          // software version
                features:               Array [0.. 3] of Byte;          // feature flags
                country:                Integer;                                        // country code
                decimals:               Integer;                                        // decimals
                escrowcap:              Integer;                                        // escrow capability
                stackercap:             Integer;                                        // stacke capacity
                bill_value:             Array [0..15] of Single;        // bill values
end;
         BLVInfoPtr     = ^BLVInfo;



function GetBLVInfo ( bip: BLVInfoPtr ): Integer; stdcall; external MDB_DLL;

Deklarace v c/c++

typedef struct {
                char                    device[13],                                     // device name
                                                model[13];                                      // model
                unsigned char   version[2],                                     // software version
                                                features[4];                            // feature flags
                int                             country,                                        // country code
                                                decimals,                                       // decimals
                                                escrowcap,                                      // escrow capability
                                                stackercap;                                     // stacke capacity
                float                   bill_value[16];                                 // bill values
} BLVInfo;


int _stdcall GetBLVInfo ( BLVInfo* bip );

Moje deklarace v C#

public class BLVInfo
        {
            public char[] device = new char[13]; // model -  device name
            public char[] model = new char[13];
            public byte[] version = new byte[2]; // feature flags -  software version
            public byte[] features = new byte[4];
            public int country; // stacke capacity -  escrow capability -  decimals -  country code
            public int decimals;
            public int escrowcap;
            public int stackercap;
            public int[] bill_value = new int[16]; // bill values
        }


[DllImport("WinMDB32.dll", CallingConvention = CallingConvention.StdCall)]
        public static extern int GetBLVInfo(BLVInfo bip);
 
Odpovědět 31.5.2014 14:46
Avatar
coells
Redaktor
Avatar
Odpovídá na hradil11
coells:

Definice, která by měla fungovat, je dole. Ještě bude záležet na tom, jestli nativní DLL bylo překládáno 32-bit nebo 64-bitovým překladačem, v tom případě se bude lišit structure packing, pak se buď musí specifikovat správná hodnota pro StructLayout nebo definovat structure offsets.

Ale upřímně, pohybuješ se na velice tenkém ledě. Marshalling je poměrně komplikovaná záležitost a vyžaduje znalost toho, jak funguje C++ i jak funguje C# marshalling a garbage collector. Soudě podle tvého řešení bych doporučil to radši nechat na někom, kdo se v tom vyzná.

Nejhorší možná scénář je, že program bude naprosto nekontrolovatelně a náhodně padat a chybu nikdy nedohledáte.

[StructLayout(LayoutKind.Sequential)]
public struct BLVInfo
{
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 13)]
    public Byte[] device;
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 13)]
    public Byte[] model;
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
    public Byte[] version;
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
    public Byte[] features;
    [MarshalAs(UnmanagedType.U4)]
    public Int32 country;
    [MarshalAs(UnmanagedType.U4)]
    public Int32 decimals;
    [MarshalAs(UnmanagedType.U4)]
    public Int32 escrowcap;
    [MarshalAs(UnmanagedType.U4)]
    public Int32 stackercap;
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
    public Int32[] bill_value;
}

[DllImport("WinMDB32.dll", CallingConvention = CallingConvention.StdCall)]
public static extern int GetBLVInfo([param: In, Out] ref BLVInfo bip);
 
Nahoru Odpovědět 31.5.2014 19:01
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 2 zpráv z 2.