Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/324.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C#:从libnotify C struct获取值_C#_.net_.net Core_Libnotify - Fatal编程技术网

C#:从libnotify C struct获取值

C#:从libnotify C struct获取值,c#,.net,.net-core,libnotify,C#,.net,.net Core,Libnotify,我正试图从我的c#代码中访问c libnotify,以便在带有dotnet内核的linux笔记本电脑上使用libnotify 但每次从库中获取值都会出现问题 这是有问题的c代码: typedef struct _NotifyNotification NotifyNotification; typedef struct _NotifyNotificationPrivate NotifyNotificationPrivate; struct _NotifyNotification { /*

我正试图从我的c#代码中访问c libnotify,以便在带有dotnet内核的linux笔记本电脑上使用libnotify
但每次从库中获取值都会出现问题

这是有问题的c代码:

typedef struct _NotifyNotification NotifyNotification;
typedef struct _NotifyNotificationPrivate NotifyNotificationPrivate;

struct _NotifyNotification
{
    /*< private >*/
    GObject                    parent_object;

    NotifyNotificationPrivate *priv;
};

struct _NotifyNotificationPrivate
{
    guint32         id;
    char           *app_name;
    char           *summary;
    char           *body;

    /* NULL to use icon data. Anything else to have server lookup icon */
    char           *icon_name;

    /*
     * -1   = use server default
     *  0   = never timeout
     *  > 0 = Number of milliseconds before we timeout
     */
    gint            timeout;

    GSList         *actions;
    GHashTable     *action_map;
    GHashTable     *hints;

    gboolean        has_nondefault_actions;
    gboolean        updates_pending;

    gulong          proxy_signal_handler;

    gint            closed_reason;
};

NotifyNotification *
notify_notification_new (const char *summary,
                     const char *body,
                     const char *icon);
使用此代码,我将所有内容强制转换为结构:

NotifyNotification no = (NotifyNotification) Marshal.PtrToStructure(not, typeof(NotifyNotification));
Console.WriteLine(Marshal.PtrToStringAnsi(no.priv.summary));
基本功能正常,我可以使用notify_notification_new-method中的指针从libnotify调用其他函数。 但在最后一行,在WriteLine中,调试器说:

The program '...dll' has exited with code 0 (0x00000000).
没有例外,也没有错误。出什么事了?这是dotnetcore的问题吗?因为它还在测试阶段

如何从属性应用程序获取文本?名称、摘要、正文

非常感谢您的帮助。

[StructLayout(LayoutKind.Explicit)]
说:“亲爱的编译器,我知道我在做什么,只是……处理一下。”。不幸的是,你不知道自己在做什么<代码>[FieldOffset]以字节为单位获取偏移量,而不是以成员为单位

struct _NotifyNotification
{
    /*< private >*/
    GObject                    parent_object;

    NotifyNotificationPrivate *priv;
};
你读

id = [01 02 03 04] => 0x04030201 (because Little-Endian)
app_name = [02 03 04 05 06 07 08 09] => 0x0908070605040302
summary = [03 04 05 06 07 08 09 0A] => 0x0A09080706050403
timeout = [06 07 08 09] => 0x09080706
最好使用顺序布局:

[StructLayout(LayoutKind.Sequential)]
internal struct NotifyNotification
{
    private IntPtr parent_object;
    public IntPtr priv;
}

[StructLayout(LayoutKind.Sequential)]
internal struct NotifyNotificationPrivate
{
    public uint id;
    public IntPtr app_name;
    public IntPtr summary;
    private IntPtr body;
    private IntPtr icon_name;
    public int timeout;
    // If you're only ever reading one of these structures
    // you can skip the rest.  If you ever allocate one, be sure to
    // include all of the fields so the right amount of memory is created
}
然后:


<> > > >编辑:,最可预测的方法是创建C库(或C++,带有<代码>外部)C“< /COD>声明”,避免了复制/解释结构(它让C编译器负责):


与之匹配的C#声明是将函数声明为返回
IntPtr
,并将其仍传递给
Marshal.PtrToStringAnsi
;因为如果你声明它返回一个
字符串
,GC会认为它应该在字符串超出范围时清理内存。

好的,谢谢你的回答。这是有道理的。但是:在将NotifyNotification指针编组到NotifyNotification结构之后,priv的值为:0x0000000000000001。因此,我无法将其封送到NotifyNotificationPrivate结构。为什么?这应该是另一个值,不是吗?@bittnerd啊,因为GObject是一个结构,而不是指针。最好的办法是制作一个小型C库,您可以将
NotifyNotification*
传入,然后将
NotifyNotificationPrivate*
传出。这样,C编译器就可以进行字段偏移量计算,并且您不需要在GNOME框架的不同版本中尝试改变GObject的结构。谢谢您的帮助。事实上,我不想用额外的图书馆这样做。但我认为这是最好的方法,我不知道还有其他方法可以得到这些值。如果您将该评论添加到您的答案中,我将接受。:)@完成了。填充(一切)是在Linux上的CoreFx中完成的方法,结构布局是最初的激励因素。(特别是对于允许有条件地编译字段的库)
id = [01 02 03 04] => 0x04030201 (because Little-Endian)
app_name = [02 03 04 05 06 07 08 09] => 0x0908070605040302
summary = [03 04 05 06 07 08 09 0A] => 0x0A09080706050403
timeout = [06 07 08 09] => 0x09080706
[StructLayout(LayoutKind.Sequential)]
internal struct NotifyNotification
{
    private IntPtr parent_object;
    public IntPtr priv;
}

[StructLayout(LayoutKind.Sequential)]
internal struct NotifyNotificationPrivate
{
    public uint id;
    public IntPtr app_name;
    public IntPtr summary;
    private IntPtr body;
    private IntPtr icon_name;
    public int timeout;
    // If you're only ever reading one of these structures
    // you can skip the rest.  If you ever allocate one, be sure to
    // include all of the fields so the right amount of memory is created
}
NotifyNotification no = (NotifyNotification) Marshal.PtrToStructure(not, typeof(NotifyNotification));
NotifyNotificationPrivate noPriv = (NotifyNotificationPrivate) Marshal.PtrToStructure(no.priv, typeof(NotifyNotificationPrivate));
Console.WriteLine(Marshal.PtrToStringAnsi(noPriv.summary));
extern "C" char* ReadNotificationSummary(NotifyNotification* notification)
{
    if (notification == nullptr || notification.priv == nullptr)
        return nullptr;

    return notification.priv->summary;
}