我设计了一个 C++ 系统,它从在单独线程中运行的过程调用用户定义的回调。简化后system.hpp
如下所示:
#pragma once
#include <atomic>
#include <chrono>
#include <functional>
#include <thread>
class System
{
public:
using Callback = std::function<void(int)>;
System(): t_(), cb_(), stop_(true) {}
~System()
{
stop();
}
bool start()
{
if (t_.joinable()) return false;
stop_ = false;
t_ = std::thread([this]()
{
while (!stop_)
{
std::this_thread::sleep_for(std::chrono::milliseconds(100));
if (cb_) cb_(1234);
}
});
return true;
}
bool stop()
{
if (!t_.joinable()) return false;
stop_ = true;
t_.join();
return true;
}
bool registerCallback(Callback cb)
{
if (t_.joinable()) return false; …
Run Code Online (Sandbox Code Playgroud) 我正在编写一个将cv::VideoCapture
类用于各种目的的类:处理实时视频流,处理离线图像序列,处理一些其他假数据.我的OpenCV版本是3.4.显然,我想到的第一个解决方案是cv::VideoCapture
为我的类提供指向某个接口的指针:
class MyClass {
public:
MyClass(std::shared_ptr<SomeInterfaceToVideoCapture> camera);
}
Run Code Online (Sandbox Code Playgroud)
我查看了OpenCV文档,实际上我发现,确实在标题中videoio.hpp
有一个前向声明IVideoCapture
(这是接口的标准命名约定).即使它似乎cv::VideoCapture
没有实际继承cv::IVideoCapture
,我尝试了一下:
class MyClass {
public:
MyClass(std::shared_ptr<cv::IVideoCapture> camera) {
if (camera->isOpened()) {
std::cerr << "VideoCapture device is not working" << std::endl;
}
}
}
// and later in GTest I create the instance like this:
MyClass myCl(new cv::VideoCapture(0));
Run Code Online (Sandbox Code Playgroud)
我收到了错误:
error: invalid use of incomplete type ‘class cv::IVideoCapture’
if (camera->isOpened()) {
/usr/local/include/opencv2/videoio.hpp:581:7: note: forward declaration of ‘class cv::IVideoCapture’
class IVideoCapture;
Run Code Online (Sandbox Code Playgroud)
所以,显然这个cv::IVideoCapture …
我想测试系统的方法,其返回值部分取决于对某种连接接口的调用的返回值。在大多数情况下,我想IConnection
返回true
对它的open(_, _)
方法的任何形式的调用。除了一种情况,当我明确测试连接失败的情况时。
例:
/*
* Some kind of network interface with method `open`
*/
class IConnection {
public:
IConnection() = default;
virtual ~IConnection() = default;
virtual bool open(const std::string& address, int port) = 0;
};
class ConnectionMock: public IConnection {
public:
MOCK_METHOD2(open, bool(const std::string& address, int port));
};
class MySystem {
public:
MySystem() = delete;
MySystem(std::shared_ptr<IConnection> connection): connection_(connection) {}
bool doSth() {
/*
* Do some things, but fail if connection fails
*/
bool …
Run Code Online (Sandbox Code Playgroud) 我尝试在内核版本为 5.0.0-38-generic 的 Linux Ubuntu 19.04 机器上从 Pleora eBUS SDK 编译一些内核模块,但出现编译错误:
error: implicit declaration of function ‘current_kernel_time’; did you mean ‘core_kernel_text’? [-Werror=implicit-function-declaration]
lTime = current_kernel_time();
Run Code Online (Sandbox Code Playgroud)
和另一个(相同的问题) function do_gettimeofday
。
我注意到了这一点,current_kernel_time
并且current_kernel_time64
在内核 v4.15 中仍然可用(例如,我的另一台机器使用 Ubuntu 18.04),最后一次出现在linux v4.19.97 中。在我的内核版本的time.h标头中,有一个函数get_timespec64
似乎在做类似的事情,但是它接受 2 个参数,对我来说似乎不正确(因为在我看到的来源中,有一个copy_from_user
被调用的)传递一些未初始化const struct __kernel_timespec __user *uts
为第二个参数。有人可以给我一些提示如何current_kernel_time
在我的较新内核版本中替换对 的调用吗?
需要修改的示例代码:
OS_UINT64 OS_TimeGetUS( OS_VOID )
{
struct timespec64 lTime;
lTime = current_kernel_time();
return ( lTime.tv_sec * 1000000 + OS_DIV64( lTime.tv_nsec, 1000 …
Run Code Online (Sandbox Code Playgroud) 在std::optional::emplace
文档中有一个接受的重载std::initializer_list
:
template< class U, class... Args >
T& emplace( std::initializer_list<U> ilist, Args&&... args );
Run Code Online (Sandbox Code Playgroud)
前提是
std::is_constructible<T, std::initializer_list&, Args&&...>::value 为真
我认为它可能用于放置 POD 类型,但显然这不是它的工作方式(在其他 SO 主题中解释说emplace
函数使用()
语法而不是{}
):
struct A
{
int x;
int y;
int z;
};
int main()
{
A normalA{1, 2, 3}; // this is OK
std::cout << std::is_constructible<A, std::initializer_list<int>&, int, int, int>::value << std::endl; // false
std::cout << std::is_constructible<A, std::initializer_list<int>&>::value << std::endl; // false
std::optional<A> optA;
// optA.emplace({1, 2, …
Run Code Online (Sandbox Code Playgroud) 我用 C 编写了一个函数,它作为参数const char *p
,我想检查该数组中的元素数量,但它不能很好地工作。
#include <stdlib.h>
#include <stdio.h>
int arrSize(const char *a){
int it = 0;
int size = 0;
while(a[it] != '\0'){
++size;
++it;
}
return size;
}
int main(){
const char a[5] = {'a', 'b', 'b', 'v', 's'};
const char b[4] = {'c', 'b', 'b', 'v'};
const char c[4] = {'c', 'b', 'b', 'v'};
printf("%d %d %d", arrSize(a), arrSize(b), arrSize(c));
}
Run Code Online (Sandbox Code Playgroud)
但上面的代码给出了 8, 12, 16 输出,我不知道为什么。
我有一个运行异步网络工作人员的系统,并定期检查工作人员是否std::exception_ptr
存储了一些信息。在这种情况下,它可能会抛出错误,或以其他方式报告错误。简单的例子:
#include <exception>
#include <gmock/gmock.h>
// simplified Network interface and the mock
struct INetwork {
virtual std::exception_ptr getExceptionPtr() const = 0;
};
struct MockedNetwork: public INetwork {
public:
MOCK_METHOD(std::exception_ptr, getExceptionPtr, (), (const override));
};
// simplified system
class System {
public:
System(INetwork& network): _network{network} {}
void run() {
// some complex logic
std::exception_ptr exPtr = _network.getExceptionPtr();
if (exPtr) {
// error handling, or just rethrow
std::rethrow_exception(exPtr);
}
}
private:
INetwork& _network;
};
Run Code Online (Sandbox Code Playgroud)
然后我想测试我的代码是否适用于以下场景
每当网络通过Exception_ptr报告错误时,系统将重新抛出该异常
所以我有这个小 gtest 测试用例:
#include …
Run Code Online (Sandbox Code Playgroud) 我正在努力处理遗留代码(已安排重构,但我现在需要使用它),该代码的设备驱动程序旨在接受(argc, argv)
其构造函数的参数。我必须使用的基类,目前我无法更改它,如下所示:
class LegacyDriver
{
public:
LegacyDriver(int argc, char** argv)
{
if (argc < 3)
{
throw std::runtime_error("nope");
}
// some logic with the arguments interpretation
int var1 = std::stoi(argv[1]);
int var2 = std::stoi(argv[2]);
std::cout << "config: " << var1 << ", " << var2 << "\n";
// etc ...
}
virtual ~LegacyDriver() = default;
// + some public interfaces, not important ...
};
Run Code Online (Sandbox Code Playgroud)
然后我的新驱动程序必须扩展此类,需要以某种方式将该argc, argv
参数传递给基类。到目前为止,我的同事们只是在玩:
class MyNewDriver: public LegacyDriver
{
public:
MyNewDriver(int argc, char** argv): …
Run Code Online (Sandbox Code Playgroud) c++ ×7
c ×2
c++11 ×1
exception ×1
gil ×1
googlemock ×1
googletest ×1
legacy-code ×1
linux-kernel ×1
opencv ×1
pointers ×1
pybind11 ×1
python ×1
size ×1
sizeof ×1
stdoptional ×1