none
PInvoke RRS feed

  • Dotaz

  • Zdravím,
    řeším teď takový problém, a potřebuji volat funkce ze staré C/C++ knihovny ze C#. Prvním pokusem byla meziknihovna napsaná v C++/CLI, která nějakým způsobem funguje. Ale nyní jsou požadovány další věci, které již takto jedou řešit mnohem hůře.

    Proto jsem si začal hrát s voláním funkcí přímo z kódu C#.

    Původní funkce knihovny je definována takto:

    Struct_Error_Context InitFingerprintImage(
    const UInt8 *i__imagedata,
    UInt32 i__imagewidth,
    UInt32 i__imageheight,
    SInt32 i__imageresolution,
    SInt8 i__fingerrank,
    Struct_Fingerprint_Image *o__FingerprintImage
    )


    K tomu jsem v C# deklaroval metodu pomocí atributu DllImport

            [
    DllImport("library.dll", EntryPoint = "InitFingerprintImage", SetLastError = true, CharSet = CharSet.Auto, ExactSpelling = true)]
    public static extern StructErrorContext InitFingerprintImage(
    [
    MarshalAs(UnmanagedType.LPArray)] byte[ ] image,
    [
    MarshalAs(UnmanagedType.U4)]UInt32 width,
    [
    MarshalAs(UnmanagedType.U4)]UInt32 height,
    [
    MarshalAs(UnmanagedType.I4)]Int32 resolution,
    [
    MarshalAs(UnmanagedType.I4)]Int32 rank,
    [
    In, Out] StructFingerprintImage fingerprintImage);


    Po zavolání se správnými parametry se mi ale vrátí struktura s chybou, že parametr height je mimo platný rozsah (256 - 4096), přičemž tento parametr má ale hodnotu 400, takže je správně.

    Datové typy jsou definovány následovně
    #ifdef __cplusplus 
    #define DLL_LINKAGE "C"
    #else
    #define DLL_LINKAGE
    #endif


    #ifdef WIN32
    #define DLL_FE_CALL_CONVENTION __cdecl
    #else
    #define DLL_FE_CALL_CONVENTION
    #endif

    /* 1 byte type (unsigned) */
    typedef unsigned char UInt8;
    extern DLL_LINKAGE const UInt8 MIN_UINT8;
    extern DLL_LINKAGE const UInt8 MAX_UINT8;

    ...


    Nenapadá vás co dělám špatně, nebo proč mi to ten parametr převede špatně? Zkoušel jsem i jiné funkce z knihovny, které nejsou na této závislé, a ty fungují správně. Tak kde je zakopaný pes confused smiley

    Zkoušel nastavit CallConvention na StdCall , WinApi i Cdecl a u všech se to chová stejně.

    Když vezmu všechny funkce, který zatím takto šli udělat, tak problém je jen s těmi, co mají jako jeden z parametrů právě const UInt8 * . Funkce, která mají jako jeden z parametrů jen ukazatel na pole UInt8 * fungují správně a vrací správný výsledek.

    Takže problém bych odhadoval na to, jestli se konstantní ukazatel nějak špatně nepřevádí.

    Zkoušel jsem i místo
    [MarshalAs(UnmanagedType.LPArray)] byte[] image

    použít
    [MarshalAs(UnmanagedType.SysUInt)]IntPtr image

    nebo dokonce i jen
    [In, Out] byte[] image

    ale výsledný efekt žádný.

    Všem díky za jakoukoliv pomoc
    -- http://rudisweb.qsh.cz/
    neděle 28. června 2009 20:25

Odpovědi