LINUX.ORG.RU

Сообщения cppprogger

 

cmake настроить jsoncpp

Форум — Development

jsoncpp в системе установлен

$ ls /usr/lib/x86_64-linux-gnu/cmake/jsoncpp
jsoncppConfig.cmake  jsoncppConfig-none.cmake

$ pkg-config --cflags --libs jsoncpp
-I/usr/include/jsoncpp -ljsoncpp

Пытаюсь найти

find_package(jsoncpp)

Как вычислить правильные имена для заголовочных файлов и бибилиотек?

message("=== Jsoncpp: "
        "\n jsoncpp_FOUND = " ${jsoncpp_FOUND}
        "\n    jsoncpp_INCLUDE_DIRS = " ${jsoncpp_INCLUDE_DIRS}
        "\n    jsoncpp_INCLUDE_DIR = " ${jsoncpp_INCLUDE_DIR}
        "\n    jsoncpp_LIBRARIES = " ${jsoncpp_LIBRARIES}
        "\n    jsoncpp_LIBRARY = " ${jsoncpp_LIBRARY}
        "\n    jsoncpp_lib = " ${jsoncpp_lib})

=== Jsoncpp: 
 jsoncpp_FOUND = 1
    jsoncpp_INCLUDE_DIRS = 
    jsoncpp_INCLUDE_DIR = 
    jsoncpp_LIBRARIES = 
    jsoncpp_LIBRARY = 
    jsoncpp_lib = 

P.S. если самому установить переменные, то все работает, конечно же

set(jsoncpp_INCLUDE_DIR "/usr/include/jsoncpp")
set(jsoncpp_LIBRARY "jsoncpp")

 ,

cppprogger
()

cmake Threads::Threads

Форум — Development

Очередной дурацкий вопрос, но гугль не помог мне.

Возможно что-то из Qt5 генерит -lThreads::Threads и в результате сборка падает с ошибкой

/usr/bin/ld: cannot find -lThreads::Threads

Что можно сделать, чтобы это исправить?

Сгенерированные от Qt правила имеют вид

set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(CMAKE_AUTOMOC ON)
find_package(Qt5Core)
...
target_link_libraries(${PROJECT_NAME} Qt5::Core)

 

cppprogger
()

cmake выбрать версию библиотеки

Форум — Development

Можно ли сказать cmake: используй конкретную версию библиотеки? Как?

Требую просто искать библиотеку

find_package(OpenSSL REQUIRED)
include_directories(${OPENSSL_INCLUDE_DIR})
#...
target_link_libraries(${PROJECT_NAME} ${OPENSSL_LIBRARIES})

Возникает проблема с линковкой другой библиотеки, использующей OpenSSL

undefined reference to symbol 'OPENSSL_sk_num@@OPENSSL_1_1_0'

В системе библиотек OpenSSL много, но удалять не хочу, т.к. они все становились с каким-то полезным софтом:

 ldconfig -p | grep ssl
	libssl3.so (libc6,x86-64) => /usr/lib/x86_64-linux-gnu/libssl3.so
	libssl.so.1.1 (libc6,x86-64) => /usr/lib/x86_64-linux-gnu/libssl.so.1.1
	libssl.so.1.0.0 (libc6,x86-64) => /usr/lib/x86_64-linux-gnu/libssl.so.1.0.0
	libssl.so (libc6,x86-64) => /usr/lib/x86_64-linux-gnu/libssl.so
	libevent_openssl-2.1.so.6 (libc6,x86-64) => /usr/lib/x86_64-linux-gnu/libevent_openssl-2.1.so.6

 , ,

cppprogger
()

отправить необработанные байты в string-e из protobuf (C++)

Форум — Development

Привет, всем!

Имеется вектор с сырыми данными

std::vector<uchar> bu;

Пытаюсь записать в поле типа string из proto3

message MyData
{
   // ...
   string image = 18;
   // ...
}

в виде std строки:

std::string((char*)bu.data(), bu.size());

получаю ошибку

[libprotobuf ERROR google/protobuf/wire_format_lite.cc:577] String field 'myservice.getMyData.image' contains invalid UTF-8 data when serializing a protocol buffer. Use the 'bytes' type if you intend to send raw bytes. 

Попытка засунуть в протобуфер сразу std::vector<uchar> закончилась на стадии компиляции

note:   no known conversion for argument 1 from ‘std::vector<unsigned char>’ to ‘const string& {aka const std::__cxx11::basic_string<char>&}’

Как правильно заполнить string из protobuf?

 ,

cppprogger
()

Перенос самописной библиотеки и so-библиотек на другой компьютер

Форум — Development

Как правильно собрать динамическую библиотеку, зависящую от других динамических библиотек (дополнительных), чтобы можно было переносить между различными компьютерами без сборки дополнительных библиотек на всех компьютерах? Является ли строгим требованием совпадение версии ядра или эту проблему можно обойти? Не уверен, что смогу найти все нужные библиотеки в виде статических (*.a).

Другими словами, есть самописная библиотека, зависящая, в частности от opencv (в общем случае и других сторонних библиотек). Переношу ее с одной Убунты 18.04 на другую. При этом посредством ldd скопировал все библиотеки, которые зависят от моей самописной. Добавляю на новый комп только те библиотеки, которых нет

lists=`ls *so*`
TARGET=/home/user/work/libs
for name in $lists ; do
    res=`ldconfig -p | grep $name`
    if [ -z "$res" ] ; then
        echo "[+] $name"
        cp $name $TARGET
    else
        echo "[-] $name"
    fi
done
Экспортирую LD_LIBRARY_PATH и получаю
UnsatisfiedLinkError: /home/user/mylibrary/bin/mylibrary.so: /lib/x86_64-linux-gnu/libm.so.6: version `GLIBC_2.27' not found (required by /home/user/libs/libopencv_imgproc.so.4.3)

Ядро у операционок различное 5.3 и 4.15. Похоже это проблема, но я не админ на целевой.

Если, я копирую все библиотеки, то в целевой ОС возникают проблемы: любая стандартная команда (ls, cat, ...) приводит к segmentation fault.

P.S. Может существует какие-то книжки или статьи по переносу, прошу порекомендовать.

 

cppprogger
()

Java c Custom Qt Library под капотом

Форум — Development

Крашится Java класс с динамической библиотекой под капотом. Библиотека основана на QCoreAppliacation. Помогите собрать, если это возможно?

$ cat src/wrapper/Client.java 
package wrapper;

import java.io.IOException;

public class Client {

    native long create();
    native void start(long ptr);

    static {
        System.load(System.getProperty("user.dir")+"/bin/libclient.so");
    }

     public static void main(String[] args) throws Exception{

        Client client = new Client();
        long ptr = client.create();
        client.start(ptr);

        char ch;
        ch = (char) System.in.read();
    }
    
}

Заголовочный JNI файл сгенерирован был автоматически

$ cat bin/wrapper_Client.h 
#include <jni.h>

#ifndef _Included_wrapper_Client
#define _Included_wrapper_Client
#ifdef __cplusplus
extern "C" {
#endif
JNIEXPORT jlong JNICALL Java_wrapper_Client_create
  (JNIEnv *, jobject);

JNIEXPORT void JNICALL Java_wrapper_Client_start
  (JNIEnv *, jobject, jlong);

#ifdef __cplusplus
}
#endif
#endif

Реализация JNI:

$ cat bin/wrapper_Client.cpp 
#include "wrapper_Client.h"
#include "qlibrary.h"


JNIEXPORT jlong JNICALL Java_wrapper_Client_create (JNIEnv *, jobject)
{
    jlong jresult = 0;
    Controller *controller;
    runApp(controller);
    *(Controller**) &jresult = controller;
    return jresult;
}


JNIEXPORT void JNICALL Java_wrapper_Client_start (JNIEnv *, jobject, jlong jptr)
{
    Controller *controller;
    controller = *(Controller **) &jptr;
    start(controller);
    
}

Команда сборки

g++ -std=c++11 -shared -fPIC -DQLIBRARY_LIBRARY -DQT_DEPRECATED_WARNINGS -DQT_NO_DEBUG -DQT_CORE_LIB -I. -isystem /usr/include/x86_64-linux-gnu/qt5 -isystem /usr/include/x86_64-linux-gnu/qt5/QtCore -I. -I/usr/lib/x86_64-linux-gnu/qt5/mkspecs/linux-g++ -o libclient.so  -I/usr/lib/jvm/java-11-openjdk-amd64/include/ -I/usr/lib/jvm/java-11-openjdk-amd64/include/linux/ wrapper_Client.cpp -lqlibrary -lQt5Core -lpthread

Имеется библиотека libqlibrary.so. Она установлена в системе и в С++ приложении нормально работает.

class Controller;

void runApp(Controller*&);
void start(Controller*&);
...

void runApp(Controller* &controller)
{
    std::thread th
    (
        [&]
        {
            int argc = 0;
            char *argv = nullptr;
            QCoreApplication app(argc, &argv);
            controller = new Controller;
            app.exec();
        }
    );
    th.detach();
}


void start(Controller*& controller)
{
    controller->start();
}
...

Запустить байт код не удается:

$ java -classpath bin wrapper.Client
#
# A fatal error has been detected by the Java Runtime Environment:
#
#  SIGSEGV (0xb) at pc=0x00007f4c9a4d08f4, pid=26982, tid=26984
#
# JRE version: OpenJDK Runtime Environment (11.0.7+10) (build 11.0.7+10-post-Ubuntu-2ubuntu218.04)
# Java VM: OpenJDK 64-Bit Server VM (11.0.7+10-post-Ubuntu-2ubuntu218.04, mixed mode, sharing, tiered, compressed oops, g1 gc, linux-amd64)
# Problematic frame:
# V  [libjvm.so+0x7178f4]

 ,

cppprogger
()

Qt условная отправка сигнала по таймеру

Форум — Development

Имеется класс со слотом, выполняющим некоторую работу, по окончанию которой должен испуститься сигнал с результатом:

class Worker : public QObject
{
    Q_OBJECT
public:
    // ...
    bool isWorking();

signals:
    void resultReady(int);

public slots:
    void doWork() {
        {
          QMutexLocker locker(&isWorkingLock_);
          isWorking_ = true;
        }
        // ...
        emit resulReady(res);
        {
          QMutexLocker locker(&isWorkingLock_);
          isWorking_ = false;
        }
    }

private:
    bool isWorking_ {false};
    QMutex isWorkingLock_;
};

worker_ типа Worker прикреплен к потоку и запускает работу doWork() по таймеру:

    workerThread_.setPriority(QThread::LowestPriority);
    worker_->moveToThread(&workerThread_);
    connect(workerTimer_, &QTimer::timeout, worker_, &Worker::doWork);
Остановка worker_ выполняется путем остановки таймера. Но, после выключения таймера некоторое время dT работа doWork() продолжается (похоже, что извлекаются сигналы, накопленные в events queue).

Как правильно снизить время dT до нуля:

1. сигнал timeout испускать при условии, что worker_.isWorking() вернул false?

вот так пробовал

    connect(workerTimer_, &QTimer::timeout, worker_, 
            [&]()
            {
                if (!worker_->isWorking()) {
                    qDebug() << "emit";
                    emit worker_->makeFrames();
                }
                else
                {
                    qDebug() << "not emit";

                }
            }
            );
но, в консоле всегда emit, и при этом проблема не решается: после остановки таймера работа doWork() повторяется некоторое время dT.

2. очистить events queue? Как правильно?

3. что-то еще? Может я неправильно понимаю ситуацию ...

 ,

cppprogger
()

RSS подписка на новые темы