gobject与C ++的接口 [英] interfacing gobject with C++

查看:121
本文介绍了gobject与C ++的接口的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用Gst :: AudioSink作为基类为gstreamer创建一个自定义音频接收器插件.对我来说,这涉及到多个学习曲线,因为我是gstreamer,gstreamermm和gobject的新手.另外,由于我目前不在使用GUI代码,因此我对gtkmm没有背景或没有真正的兴趣.

I’m trying to create a custom audio sink plugin for gstreamer using the Gst::AudioSink as a base class. For me this involves multiple learning curves as I’m new to gstreamer, gstreamermm and gobject. Also I have no background or real interest in gtkmm as I’m not working on GUI code at present.

我正在尝试按照以下方式创建一个类:

I am trying to create a class along the lines of:

class MyAudioSink: public Gst::AudioSink
{
public:
    explicit MyAudioSink(KantarAudioSink *gobj);
    virtual ~MyAudioSink();

    static void class_init(Gst::ElementClass<MyAudioSink> *klass);

    virtual int write_vfunc(gpointer data, guint length) override;
    virtual void reset_vfunc();
};

我似乎在 class_init()函数中缺少一些魔术,这些魔术应该将基类函数链接到MyAudioSink中的虚函数. 在C语言中,我们将执行以下操作:

I seem to missing some magic in the class_init() function that should link the base class functions to the virtual functions in MyAudioSink. In C we would do something like:

  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
  GstAudioSinkClass *audio_sink_class = GST_AUDIO_SINK_CLASS (klass);
  audio_sink_class->write = GST_DEBUG_FUNCPTR (myaudiosink_write);

我并不是真的不喜欢C ++与gobject的绑定. 链接到C ++虚拟函数层次结构等效于什么?

I don’t really grok the C++ binding to gobject. What is the equivalent for linking to the C++ virtual function hierarchy?

我对Marcin的视频 https://gstconf.ubicast.tv/videos/gstreamermm-c-way-of-doing-gstreamer-based-applications/应该自动调用虚拟功能.

I got the impression from Marcin’s video https://gstconf.ubicast.tv/videos/gstreamermm-c-way-of-doing-gstreamer-based-applications/ that the virtual functions should be invoked automatically.

我可以通过添加以下内容来创建一个半可用的(不处理EOS之类的)插件:

I can create a half usable (doesn’t handle things like EOS) plugin by adding:

   add_pad(sinkpad = Gst::Pad::create(get_pad_template("sink"), "sink"));
   sinkpad->set_chain_function(sigc::mem_fun(*this, &MyAudioSink::chain));

但是我不认为接收器应该具有链功能.

But I don't think a sink should have a chain function.

我也在gtkmm邮件列表上问了这个问题.如果我在那里得到答案,我会在这里发布.

I've also asked this question on the gtkmm mailing list. If I get an answer there I will post it here.

对于MyAudioSink,我得到的类层次结构为:

For MyAudioSink I get a class hierarchy of:

GObject + ---- GInitiallyUnown + ---- GstObject + ---- GstElement + ---- myaudiosink

GObject +----GInitiallyUnowned +----GstObject +----GstElement +----myaudiosink

而不是:

GObject + ---- GInitiallyUnown + ---- GstObject + ---- GstElement + ---- GstBaseAudioSink + ---- GstAudioSink + ---- myaudiosink

GObject +----GInitiallyUnowned +----GstObject +----GstElement +----GstBaseAudioSink +----GstAudioSink +----myaudiosink

我怀疑这是我问题的本质.

I suspect this is the essence of my problem.

在音频过滤器示例中,Marcin在此处提到了一个类层次结构:

For the audiofilter example Marcin mentions here I get a class hierachy of:

GObject + ---- GInitiallyUnown + ---- GstObject + ---- GstElement + ---- GstBaseTransform + ---- GstAudioFilter + ---- myaudiofilter

GObject +----GInitiallyUnowned +----GstObject +----GstElement +----GstBaseTransform +----GstAudioFilter +----myaudiofilter

推荐答案

事实证明,我的很多麻烦都是由于剪切和粘贴引起的 这进入MyAudioSink类:

It turns out that much of my troubles were caused by cutting and pasting this into MyAudioSink class:

static GType get_base_type()
    {
       return Element::get_base_type();
    }

这具有告诉gobject我的类基于 gstElement 的作用,这是错误的. 我以为这是一些天真烂漫的咒语. 这显示了剪切和粘贴的危险,但比盲目地编码的危险要大得多. 我也对简化粘贴在此处的示例代码感到内gui,以至于我的问题中没有一个没有显示出问题所在.

This had the effect of telling gobject that my class is based on gstElement which was wrong. I thought it was some innocent cast like incantation. This shows the perils of cut and paste but more than that the perils of coding blindly. I was also guilty of oversimplifying the sample code I pasted here such that no-one my question doesn't show the problem.

那可以解决我的问题,但不能回答我的问题. 我将在下面尝试总结一下.

That fixes my problem but does not answer my question. I will try to summarise that below.

链接到C ++虚拟函数层次结构的等效项是什么?"

要为gobject类创建包装,正常过程是使用 glibmmproc . 包装器由扩展名为.hg和.ccg的文件定义,从中生成C ++接口和 gobject 包装器.

To create a wrapper to a gobject class the normal process is to use glibmmproc. The wrapper is defined by files with extension .hg and .ccg from which the C++ interface and a gobject wrapper are generated.

例如,要包装gobject类 foo ,您可以创建Foo.hg和Foo.ccg. 然后 glibmmproc 将生成Foo.h和Foo.cc. Foo.cc包含您对Foo类的大部分定义,但包含 另一个gobject包装器 Foo_class .

For example to wrap a gobject classs foo you might create Foo.hg and Foo.ccg. glibmmproc would then generate Foo.h and Foo.cc. Foo.cc includes most of your definition of the Foo class but with an additional gobject wrapper Foo_class.

Foo_class 是一个gobject类,用于包装gobject虚拟函数(vfunc_callbacks)并将其转发给Foo 允许Foo的派生类使用C ++继承和C ++虚拟函数. 隐藏了样板,C ++开发人员大部分只需要担心Foo.h提供的C ++接口.

Foo_class is a gobject class which wraps gobject virtual functions (vfunc_callbacks) and forwards them to Foo allowing derived classes of Foo to use C++ inheritance and C++ virtual functions. The boilerplate is hidden and a C++ developer need for the most part only worry about the C++ interface provided by Foo.h

了解内部原理的一种方法是从源代码构建gstreamermm并研究glibmmproc生成的代码. 就我而言,这将是:gstreamermm/audiosink.cc&从生成的gstreamermm/audiosink.h src/audiosink.ccg和src/audiosink.hg

One way to understand the internals is to build gstreamermm from source and study the code generated by glibmmproc. For my case this would be: gstreamermm/audiosink.cc & gstreamermm/audiosink.h generated from src/audiosink.ccg and src/audiosink.hg

那么 派生的C ++类如何进行自身注册?

So how does the derived C++ class register itself?

  • Gst :: ElementFactory :: register_element()-向gstreamer注册该类
  • Gst :: register_mm_type -记录继承关系
  • Gst::ElementFactory::register_element() - registers the class with gstreamer
  • Gst::register_mm_type - records the inheritance relationship

有关实现,请参见您本地的/usr/include/gstreamermm-1.0/gstreamermm/register.h

See your local /usr/include/gstreamermm-1.0/gstreamermm/register.h for the implementation

Glib :: ObjectBase(typeid(MyAudioSink)),因为我没有使用多重继承.但是,在其他这样做的应用程序中,这一点至关重要.参见例如实现自定义gtkmm树模型

Glib::ObjectBase(typeid (MyAudioSink)) is not required in my case as I am not using multiple inheritance. However it is critical in other applications which do. See for example Implementing a custom gtkmm treemodel

这篇关于gobject与C ++的接口的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆