九环

导航

Linux 下 C# Mono P/Invoke .so 动态链接库。

 

linux 的动态链接库 libgw.so 的函数 如下:

 1 struct lbt_chan
 2 {
 3     uint32_t freq_hz;
 4     uint16_t scan_time_us;
 5 };
 6 struct lgw_conf_lbt_s 
 7 {
 8     bool                        enable;         
 9     int8_t                      rssi_target;       
10     uint8_t                     nb_channel;       
11     struct lbt_chan             channels[8];
12     int8_t                      rssi_offset;       
13 };
14 
15 int board_setconf(struct conf_lbt_s cfg);
16 int board_setconf2(struct conf_lbt_s* cfg);

 

C#封装如下:

using System.Runtime.InteropServices;

[StructLayout(LayoutKind.Sequential)]
public struct lbt_chan
{
    public UInt32 freq_hz;
    public UInt16 scan_time_us;
};
        
[StructLayout(LayoutKind.Sequential)]
public struct conf_lbt_s
{
    [MarshalAs(UnmanagedType.I1)]
    public bool         enable;
    
    public sbyte         rssi_target;
    public byte         nb_channel;
    
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8, ArraySubType = UnmanagedType.Struct)]
    public lbt_chan[]     channels;
    
    public sbyte         rssi_offset;
};


[DllImport(@"libgw.so", EntryPoint = "board_setconf", CallingConvention = CallingConvention.Cdecl)]
extern public static Int32 board_setconf(conf_lbt_s cfg);

[DllImport(@"libgw.so", EntryPoint = "board_setconf2", CallingConvention = CallingConvention.Cdecl)]
extern public static Int32 board_setconf2([MarshalAs(UnmanagedType.LPStruct)]conf_lbt_s cfg);

 

封装和win环境下一般无二。

这俩函数基本可以总结全部内容了。

 

特别要注意的是  CallingConvention = CallingConvention.Cdecl

  调用约定:

  1、Cdecl   调用方清理堆栈。 这使您能够调用具有 varargs 的函数(如 Printf),使之可用于接受可变数目的参数的方法。

  2、FastCall   不支持此调用约定。     

  3、StdCall   被调用方清理堆栈。这是使用平台invoke调用非托管函数的默认约定。     

  4、ThisCall   第一个参数是 this 指针,它存储在寄存器 ECX 中。 其他参数被推送到堆栈上。 此调用约定用于对从非托管 DLL 导出的类调用方法。   

  5、Winapi   此成员实际上不是调用约定,而是使用了默认平台调用约定。 例如,在 Windows 上默认为 StdCall,在 Windows CE.NET 上默认为 Cdecl。

 

posted on 2018-05-24 21:28  九环  阅读(731)  评论(1编辑  收藏  举报