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
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/