none
Lze vůbec z C# volat DLL funkci psanou v C a předávající jako result pointer na strukturu ?

    Dotaz

  • Tak jsem se mořil s InteropServices a Marshal, ale nedobral jsem se řešení. Mám obsahlou library s funkcemi z C (ne C++, jen C) které jsou publikovány v DLL. Bohužel jak bývalo zvykem návratovou hodnotou je většinou pointer na strukturu (tedy v unmanaged paměti, alokovanou předešlými unmanaged funkcemi). Nepodařilo se mě ale z navráceného pointeru (který jsem přetypoval jako IntPtr) získat jakákoliv data. V nejlepším případě mě to hlásí chybu ArgumentException "Struktura nesmí být třídou hodnot" při Marshal.PtrToStructure. Má někdo řešení či doporučení ?

    ----------------------------------------------------------------------------------------------------

    Struktura v původním C:

    typedef struct my_data_rec{

    unsigned char type; // offset 0, length 1

    unsigned short len;  // offset 2, length 2 (alignment default on 2)

    unsigned short elem; // offset 4, length 2

    unsigned char fill[2]; /* force alignment on double boundary */

    char               value[65534]; //pole znaku ASCIZ ruzne delky

    } MY_DATA_STRUCT;

     

    To jsem deklaroval v C# jako:

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]

    public struct MY_DATA_STRUCT

    {

    [MarshalAs(UnmanagedType.I1)]

    public byte typ;            

    [MarshalAs(UnmanagedType.U2)]

    public ushort len; 

    [MarshalAs(UnmanagedType.U2)]

    public ushort elem;  

    [MarshalAs(UnmanagedType.I1, SizeConst = 2)]

    public string fill;

    [MarshalAs(UnmanagedType.I1, SizeConst = 65534)]

    public string hodnota;

    }

    [DllImport("Select.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.Cdecl)]

    static extern IntPtr StartSelection();

     

    a použité rutiny z InteropServices:

    IntPtr p;

    MY_DATA_STRUCT pole;

     

    p = StartSelection();

    Marshal.PtrToStructure(p, pole); // hlásí chybu "Struktura nesmí být třídou hodnot"

    -----------------------------------------------------------------------------

    Díky za nápady a rady či upozornění kde dělám chybu. Dll a lib mohu zaslat.

    20. června 2008 14:06

Odpovědi

  • Osobne bych strukturu v C# zkusil nadeklarovat treba nejak takto

     

    Code Snippet

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]

    public class MY_DATA_STRUCT

    {

    public byte b;

    public ushort len;

    public ushort elem;

     

    [MarshalAs(UnmanagedType.ByValArray, SizeConst=2)]

    public char[] fill;

     

    [MarshalAs(UnmanagedType.ByValArray, SizeConst=65534)]

    public char[] data;

    }

     

    [DllImport("Select.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]

    public static extern MY_DATA_STRUCT StartSelection();

     

    26. června 2008 9:06
    Přispěvatel