我在 C# WinForms 应用程序中使用gstreamer 1.8.1 库,它允许我同时观看来自视频服务器设备的多个 RTSP 视频流。
我编写了一个本机 c++ dll,它包装了对 gstreamer 的调用。我通过 DllImport 属性从 C# 应用程序使用它。
大多数时候一切都很完美。但有时(我认为当与视频服务器的连接不稳定时)我gst_element_set_state(pipeline, GST_STATE_NULL);的本机 dll 中出现死锁。
对 gstreamer API 的所有调用都是从主 (GUI) 线程进行的。死锁发生的情况非常罕见——每天只发生一次。发现这个错误非常乏味,而且我不知道如何修复或解决它。
以下是发生死锁时 Visual Studio 调试器的一些屏幕截图:
gstreamer 包装器 dll 的源代码非常小:
#pragma comment(lib, "gstreamer-1.0.lib")
#pragma comment(lib, "glib-2.0.lib")
#pragma comment(lib, "gobject-2.0.lib")
#pragma comment(lib, "gstvideo-1.0.lib")
GSTLIB_API void init()
{
gst_init(NULL, NULL);
}
GSTLIB_API GstElement* create(const char* uri, const void* hwnd)
{
GstElement* pipeline = gst_element_factory_make("playbin", "play");
g_object_set(G_OBJECT(pipeline), "uri", uri, NULL);
gst_video_overlay_set_window_handle(GST_VIDEO_OVERLAY(pipeline), (guintptr)hwnd);
return pipeline;
} …Run Code Online (Sandbox Code Playgroud) 根据问题string array [] =""是什么; 意思是,它为什么有效?我想问一下下面代码中s1和s2之间的区别:
int main() {
const char* s1 = { "Hello" }; // strange but work as followed
const char* s2 = "Hello"; // ordinary case
return 0;
}
Run Code Online (Sandbox Code Playgroud)
为什么允许额外的花括号?任何对C++标准的引用都会很有用.
请考虑以下代码段:
struct S
{
S( const int a )
{
this->a = a; // option 1
S::a = a; // option 2
}
int a;
};
Run Code Online (Sandbox Code Playgroud)
选项1是否等同于选项2?是否存在一种形式比另一种形式更好的情况?标准的哪个条款描述了这些选项?
假设存在"温度"(T)和"距离"(D)的类型.实际上,两者都可以声明为通常的typedef:
typedef int T; // might be C++11 'using'
typedef int D;
Run Code Online (Sandbox Code Playgroud)
但是如果我想要一个重载函数:
void f(T) {}
void f(D) {}
Run Code Online (Sandbox Code Playgroud)
它不起作用,因为两种类型都是相同的.
哪种最现代的C++ - 实现这种过载的方式?
很明显,对于那些类型必须可以区分编译器.
考虑以下代码:
#include <iostream>
#include <math.h>
double log(double) { return 42; }
int main() {
std::cout << log(1) << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
构建调试版本时所有使用的编译器(msvc,gcc,clang)打印42.
但是当我在发布模式下尝试构建(并运行)时,我得到了:
error C2169: 'log' : intrinsic function, cannot be defined;42gcc;0为铿锵打印.为什么同一编译器的发布/调试结果不同?
为什么在发布模式下为不同的编译器获得不同的结果?
请考虑以下代码:
#include <iostream>
class S {
static const int i = 42;
template <class T>
friend void f();
};
template <class T>
void f()
{
std::cout << S::i << "\n";
}
int main()
{
f<int>();
f<double>();
}
Run Code Online (Sandbox Code Playgroud)
所有我想在这里是允许访问类的私有部分S来 f<int>,但不适合f<double>.即我想获得编译器错误,如'i' is a private member of 'S'用于f<double>()线.
如何实现这一目标?
我需要一个运行时大小已知的容器,而无需调整大小。std::unique_ptr<T[]>会很有用,但没有封装的size成员。同时std::array只适用于编译类型的大小。因此,我需要这些类的某种组合,而没有/最小的开销。
是否有满足我需求的标准类,也许在即将发布的C ++ 20中有?
出于某种原因,在clang 中仍然缺乏预期的CTAD:std::initializer_list
std::initializer_list l{1,2,3}; // error in clang
Run Code Online (Sandbox Code Playgroud)
添加如下所示的用户定义指南可以解决此问题:
namespace std {
template<class T>
initializer_list(const initializer_list<T>&) -> initializer_list<T>;
}
Run Code Online (Sandbox Code Playgroud)
但是是否允许为std::类型添加用户定义的 CTAD 指南?
考虑以下代码:
#include <iostream>
struct M {
M() { std::cout << "M\n"; }
};
template <class T>
struct Test {
Test() { std::cout << "Test\n"; }
inline static auto m = M{};
};
int main() {
Test<int> t1;
//Test t;
//(void)&t1.m;
}
Run Code Online (Sandbox Code Playgroud)
使用最新的GCC或Clang打印出唯一的“测试”。但是,如果我们使用地址的m(取消注释最后一行对象(void)&t1.m;)或转换Test类模板到常规(非模板)类则M构造函数被调用。
C++ 标准允许这种行为吗?任何报价?
考虑以下代码:
#include <iostream>
#include <thread>
int main() {
std::thread t;
const auto l = [x = std::move(t)]{};
decltype(l) m = std::move(l);
}
Run Code Online (Sandbox Code Playgroud)
此代码不会编译为以下消息:
Run Code Online (Sandbox Code Playgroud)prog.cc: In function 'int main()': prog.cc:7:32: error: use of deleted function 'main()::<lambda()>::<lambda>(const main()::<lambda()>&)' 7 | decltype(l) m = std::move(l); | ^ prog.cc:6:37: note: 'main()::<lambda()>::<lambda>(const main()::<lambda()>&)' is implicitly deleted because the default definition would be ill-formed: 6 | const auto l = [x = std::move(t)]{}; | ^ prog.cc:6:37: error: use of deleted function 'std::thread::thread(const std::thread&)' In …