mystor / rust-cpp

Embed C++ directly inside your rust code!
Apache License 2.0
795 stars 44 forks source link

Error while Wrapping a C++ Class #98

Closed Ayush1325 closed 2 years ago

Ayush1325 commented 2 years ago

I am trying to create a wrapper for klocalizedtranslator class KDE KI18n Library. I am getting the following error:

warning: src/klocalizedtranslator.rs: In function ‘KLocalizedTranslator __cpp_closure_17134116844689587466_impl(QObject* const&)’:
warning: src/klocalizedtranslator.rs:19:48: error: use of deleted function ‘KLocalizedTranslator::KLocalizedTranslator(const KLocalizedTranslator&)’
warning:    19 |             return KLocalizedTranslator(obj_ptr);
warning:       |                                                ^
warning: In file included from /usr/include/KF5/KI18n/KLocalizedTranslator:1,
warning:                  from src/klocalizedtranslator.rs:7:
warning: /usr/include/KF5/KI18n/klocalizedtranslator.h:55:20: note: ‘KLocalizedTranslator::KLocalizedTranslator(const KLocalizedTranslator&)’ is implicitly deleted because the default definition would be ill-formed:
warning:    55 | class KI18N_EXPORT KLocalizedTranslator : public QTranslator
warning:       |                    ^~~~~~~~~~~~~~~~~~~~
warning: /usr/include/KF5/KI18n/klocalizedtranslator.h:55:20: error: use of deleted function ‘QTranslator::QTranslator(const QTranslator&)’
warning: In file included from /usr/include/qt/QtCore/qnamespace.h:43,
warning:                  from /usr/include/qt/QtCore/qobjectdefs.h:48,
warning:                  from /usr/include/qt/QtCore/qobject.h:46,
warning:                  from /usr/include/qt/QtCore/QObject:1,
warning:                  from /usr/include/KF5/KI18n/klocalizedcontext.h:11,
warning:                  from /usr/include/KF5/KI18n/KLocalizedContext:1,
warning:                  from src/klocalizedcontext.rs:9:
warning: /usr/include/qt/QtCore/qtranslator.h:81:20: note: declared here
warning:    81 |     Q_DISABLE_COPY(QTranslator)
warning:       |                    ^~~~~~~~~~~
warning: /usr/include/qt/QtCore/qglobal.h:443:5: note: in definition of macro ‘Q_DISABLE_COPY’
warning:   443 |     Class(const Class &) = delete;\
warning:       |     ^~~~~
warning: In file included from /usr/include/KF5/KI18n/KLocalizedTranslator:1,
warning:                  from src/klocalizedtranslator.rs:7:
warning: /usr/include/KF5/KI18n/klocalizedtranslator.h:55:20: error: use of deleted function ‘std::unique_ptr<_Tp, _Dp>::unique_ptr(const std::unique_ptr<_Tp, _Dp>&) [with _Tp = KLocalizedTranslatorPrivate; _Dp = std::default_delete<KLocalizedTranslatorPrivate>]’
warning:    55 | class KI18N_EXPORT KLocalizedTranslator : public QTranslator
warning:       |                    ^~~~~~~~~~~~~~~~~~~~
warning: In file included from /usr/include/c++/11.1.0/memory:76,
warning:                  from /usr/include/KF5/KI18n/klocalizedcontext.h:14,
warning:                  from /usr/include/KF5/KI18n/KLocalizedContext:1,
warning:                  from src/klocalizedcontext.rs:9:
warning: /usr/include/c++/11.1.0/bits/unique_ptr.h:468:7: note: declared here
warning:   468 |       unique_ptr(const unique_ptr&) = delete;
warning:       |       ^~~~~~~~~~
warning: src/klocalizedtranslator.rs: In function ‘void __cpp_closure_17134116844689587466(QObject* const&, void*)’:
warning: src/klocalizedtranslator.rs:24:92: error: use of deleted function ‘KLocalizedTranslator::KLocalizedTranslator(const KLocalizedTranslator&)’

I think it is being caused since the cpp_class! macro tries to implement the copy trait automatically.

I am quite sure that it should be possible to create a wrapper by using a C++ class containing a unique pointer to the KLocalizedTranslator object instead. However, I want to understand what the above error actually means rather than just a solution. since I have been using rust_cpp crate quite a lot recently.

ogoffart commented 2 years ago

Please make a self contained example that reproduces the problem.

Looking at the error log now, it looks as is there is an actual error in the c++ code written inline.

Ayush1325 commented 2 years ago

Ok, so here is my main file with the problem. I don't think this can be run directly though without a custom build.rs.

use cpp::{cpp, cpp_class};
use qmetaobject::{QObject, QObjectPinned};

cpp! {{
    #include <KLocalizedTranslator>
}}

cpp_class!(
    pub unsafe struct KLocalizedTranslator as "KLocalizedTranslator"
);

impl KLocalizedTranslator {
    #[cfg(feature = "qmetaobject")]
    pub fn new<T: QObject + Sized>(obj: QObjectPinned<T>) -> KLocalizedTranslator {
        let obj_ptr = obj.get_or_create_cpp_object();
        cpp!(unsafe [obj_ptr as "QObject *"] -> KLocalizedTranslator as "KLocalizedTranslator" {
            return KLocalizedTranslator(obj_ptr);
        })
    }
}

The code can also be found in my project here. You can just clone the repo and try to build the project to get the error. The requirements are mentioned in the Readme.

Here is the complete error log but the error log I posted above contains the important parts I thought were responsible.

warning: src/klocalizedtranslator.rs: In function ‘KLocalizedTranslator __cpp_closure_17134116844689587466_impl(QObject* const&)’:
warning: src/klocalizedtranslator.rs:19:48: error: use of deleted function ‘KLocalizedTranslator::KLocalizedTranslator(const KLocalizedTranslator&)’
warning:    19 |             return KLocalizedTranslator(obj_ptr);
warning:       |                                                ^
warning: In file included from /usr/include/KF5/KI18n/KLocalizedTranslator:1,
warning:                  from src/klocalizedtranslator.rs:7:
warning: /usr/include/KF5/KI18n/klocalizedtranslator.h:55:20: note: ‘KLocalizedTranslator::KLocalizedTranslator(const KLocalizedTranslator&)’ is implicitly deleted because the default definition would be ill-formed:
warning:    55 | class KI18N_EXPORT KLocalizedTranslator : public QTranslator
warning:       |                    ^~~~~~~~~~~~~~~~~~~~
warning: /usr/include/KF5/KI18n/klocalizedtranslator.h:55:20: error: use of deleted function ‘QTranslator::QTranslator(const QTranslator&)’
warning: In file included from /usr/include/qt/QtCore/qnamespace.h:43,
warning:                  from /usr/include/qt/QtCore/qobjectdefs.h:48,
warning:                  from /usr/include/qt/QtCore/qobject.h:46,
warning:                  from /usr/include/qt/QtCore/QObject:1,
warning:                  from /usr/include/KF5/KI18n/klocalizedcontext.h:11,
warning:                  from /usr/include/KF5/KI18n/KLocalizedContext:1,
warning:                  from src/klocalizedcontext.rs:9:
warning: /usr/include/qt/QtCore/qtranslator.h:81:20: note: declared here
warning:    81 |     Q_DISABLE_COPY(QTranslator)
warning:       |                    ^~~~~~~~~~~
warning: /usr/include/qt/QtCore/qglobal.h:443:5: note: in definition of macro ‘Q_DISABLE_COPY’
warning:   443 |     Class(const Class &) = delete;\
warning:       |     ^~~~~
warning: In file included from /usr/include/KF5/KI18n/KLocalizedTranslator:1,
warning:                  from src/klocalizedtranslator.rs:7:
warning: /usr/include/KF5/KI18n/klocalizedtranslator.h:55:20: error: use of deleted function ‘std::unique_ptr<_Tp, _Dp>::unique_ptr(const std::unique_ptr<_Tp, _Dp>&) [with _Tp = KLocalizedTranslatorPrivate; _Dp = std::default_delete<KLocalizedTranslatorPrivate>]’
warning:    55 | class KI18N_EXPORT KLocalizedTranslator : public QTranslator
warning:       |                    ^~~~~~~~~~~~~~~~~~~~
warning: In file included from /usr/include/c++/11.1.0/memory:76,
warning:                  from /usr/include/KF5/KI18n/klocalizedcontext.h:14,
warning:                  from /usr/include/KF5/KI18n/KLocalizedContext:1,
warning:                  from src/klocalizedcontext.rs:9:
warning: /usr/include/c++/11.1.0/bits/unique_ptr.h:468:7: note: declared here
warning:   468 |       unique_ptr(const unique_ptr&) = delete;
warning:       |       ^~~~~~~~~~
warning: src/klocalizedtranslator.rs: In function ‘void __cpp_closure_17134116844689587466(QObject* const&, void*)’:
warning: src/klocalizedtranslator.rs:24:92: error: use of deleted function ‘KLocalizedTranslator::KLocalizedTranslator(const KLocalizedTranslator&)’

error: failed to run custom build command for `ki18n v1.0.6 (/home/ayush/Documents/Programming/Rust/ki18n-rs)`

Caused by:
  process didn't exit successfully: `/home/ayush/Documents/Programming/Rust/ki18n-rs/target/debug/build/ki18n-cbbb8a0e1e64377d/build-script-build` (exit status: 1)
  --- stdout
  cargo:rerun-if-env-changed=KF5_INCLUDE_PATH
  cargo:rerun-if-env-changed=KF5_LIBRARY_PATH
  cargo:rustc-link-search=/usr/lib
  cargo:rustc-link-lib=KF5I18n
  TARGET = Some("x86_64-unknown-linux-gnu")
  OPT_LEVEL = Some("0")
  HOST = Some("x86_64-unknown-linux-gnu")
  CXX_x86_64-unknown-linux-gnu = None
  CXX_x86_64_unknown_linux_gnu = None
  HOST_CXX = None
  CXX = None
  CXXFLAGS_x86_64-unknown-linux-gnu = None
  CXXFLAGS_x86_64_unknown_linux_gnu = None
  HOST_CXXFLAGS = None
  CXXFLAGS = None
  CRATE_CC_NO_DEFAULTS = None
  DEBUG = Some("true")
  CARGO_CFG_TARGET_FEATURE = Some("fxsr,sse,sse2")
  CXX_x86_64-unknown-linux-gnu = None
  CXX_x86_64_unknown_linux_gnu = None
  HOST_CXX = None
  CXX = None
  CXXFLAGS_x86_64-unknown-linux-gnu = None
  CXXFLAGS_x86_64_unknown_linux_gnu = None
  HOST_CXXFLAGS = None
  CXXFLAGS = None
  CRATE_CC_NO_DEFAULTS = None
  CARGO_CFG_TARGET_FEATURE = Some("fxsr,sse,sse2")
  running: "c++" "-O0" "-ffunction-sections" "-fdata-sections" "-fPIC" "-g" "-fno-omit-frame-pointer" "-m64" "-I" "/home/ayush/Documents/Programming/Rust/ki18n-rs" "-I" "/usr/include/qt" "-I" "/usr/include/qt/QtCore" "-I" "/usr/include/KF5/KI18n" "-Wall" "-Wextra" "-std=c++11" "-o" "/home/ayush/Documents/Programming/Rust/ki18n-rs/target/debug/build/ki18n-f4b48303895c005d/out/rust_cpp/cpp_closures.o" "-c" "/home/ayush/Documents/Programming/Rust/ki18n-rs/target/debug/build/ki18n-f4b48303895c005d/out/rust_cpp/cpp_closures.cpp"
  cargo:warning=src/klocalizedtranslator.rs: In function ‘KLocalizedTranslator __cpp_closure_17134116844689587466_impl(QObject* const&)’:
  cargo:warning=src/klocalizedtranslator.rs:19:48: error: use of deleted function ‘KLocalizedTranslator::KLocalizedTranslator(const KLocalizedTranslator&)’
  cargo:warning=   19 |             return KLocalizedTranslator(obj_ptr);
  cargo:warning=      |                                                ^
  cargo:warning=In file included from /usr/include/KF5/KI18n/KLocalizedTranslator:1,
  cargo:warning=                 from src/klocalizedtranslator.rs:7:
  cargo:warning=/usr/include/KF5/KI18n/klocalizedtranslator.h:55:20: note: ‘KLocalizedTranslator::KLocalizedTranslator(const KLocalizedTranslator&)’ is implicitly deleted because the default definition would be ill-formed:
  cargo:warning=   55 | class KI18N_EXPORT KLocalizedTranslator : public QTranslator
  cargo:warning=      |                    ^~~~~~~~~~~~~~~~~~~~
  cargo:warning=/usr/include/KF5/KI18n/klocalizedtranslator.h:55:20: error: use of deleted function ‘QTranslator::QTranslator(const QTranslator&)’
  cargo:warning=In file included from /usr/include/qt/QtCore/qnamespace.h:43,
  cargo:warning=                 from /usr/include/qt/QtCore/qobjectdefs.h:48,
  cargo:warning=                 from /usr/include/qt/QtCore/qobject.h:46,
  cargo:warning=                 from /usr/include/qt/QtCore/QObject:1,
  cargo:warning=                 from /usr/include/KF5/KI18n/klocalizedcontext.h:11,
  cargo:warning=                 from /usr/include/KF5/KI18n/KLocalizedContext:1,
  cargo:warning=                 from src/klocalizedcontext.rs:9:
  cargo:warning=/usr/include/qt/QtCore/qtranslator.h:81:20: note: declared here
  cargo:warning=   81 |     Q_DISABLE_COPY(QTranslator)
  cargo:warning=      |                    ^~~~~~~~~~~
  cargo:warning=/usr/include/qt/QtCore/qglobal.h:443:5: note: in definition of macro ‘Q_DISABLE_COPY’
  cargo:warning=  443 |     Class(const Class &) = delete;\
  cargo:warning=      |     ^~~~~
  cargo:warning=In file included from /usr/include/KF5/KI18n/KLocalizedTranslator:1,
  cargo:warning=                 from src/klocalizedtranslator.rs:7:
  cargo:warning=/usr/include/KF5/KI18n/klocalizedtranslator.h:55:20: error: use of deleted function ‘std::unique_ptr<_Tp, _Dp>::unique_ptr(const std::unique_ptr<_Tp, _Dp>&) [with _Tp = KLocalizedTranslatorPrivate; _Dp = std::default_delete<KLocalizedTranslatorPrivate>]’
  cargo:warning=   55 | class KI18N_EXPORT KLocalizedTranslator : public QTranslator
  cargo:warning=      |                    ^~~~~~~~~~~~~~~~~~~~
  cargo:warning=In file included from /usr/include/c++/11.1.0/memory:76,
  cargo:warning=                 from /usr/include/KF5/KI18n/klocalizedcontext.h:14,
  cargo:warning=                 from /usr/include/KF5/KI18n/KLocalizedContext:1,
  cargo:warning=                 from src/klocalizedcontext.rs:9:
  cargo:warning=/usr/include/c++/11.1.0/bits/unique_ptr.h:468:7: note: declared here
  cargo:warning=  468 |       unique_ptr(const unique_ptr&) = delete;
  cargo:warning=      |       ^~~~~~~~~~
  cargo:warning=src/klocalizedtranslator.rs: In function ‘void __cpp_closure_17134116844689587466(QObject* const&, void*)’:
  cargo:warning=src/klocalizedtranslator.rs:24:92: error: use of deleted function ‘KLocalizedTranslator::KLocalizedTranslator(const KLocalizedTranslator&)’
  exit status: 1

  --- stderr
  cargo:warning=[("CARGO", "/home/ayush/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/bin/cargo"), ("CARGO_CFG_TARGET_ARCH", "x86_64"), ("CARGO_CFG_TARGET_ENDIAN", "little"), ("CARGO_CFG_TARGET_ENV", "gnu"), ("CARGO_CFG_TARGET_FAMILY", "unix"), ("CARGO_CFG_TARGET_FEATURE", "fxsr,sse,sse2"), ("CARGO_CFG_TARGET_OS", "linux"), ("CARGO_CFG_TARGET_POINTER_WIDTH", "64"), ("CARGO_CFG_TARGET_VENDOR", "unknown"), ("CARGO_CFG_UNIX", ""), ("CARGO_ENCODED_RUSTFLAGS", ""), ("CARGO_HOME", "/home/ayush/.cargo"), ("CARGO_MAKEFLAGS", "-j --jobserver-fds=10,11 --jobserver-auth=10,11"), ("CARGO_MANIFEST_DIR", "/home/ayush/Documents/Programming/Rust/ki18n-rs"), ("CARGO_MANIFEST_LINKS", "KF5I18n"), ("CARGO_PKG_AUTHORS", ""), ("CARGO_PKG_DESCRIPTION", "A crate to use KF5I18n from rust."), ("CARGO_PKG_HOMEPAGE", ""), ("CARGO_PKG_LICENSE", "MIT"), ("CARGO_PKG_LICENSE_FILE", ""), ("CARGO_PKG_NAME", "ki18n"), ("CARGO_PKG_REPOSITORY", "https://github.com/Ayush1325/ki18n-rs"), ("CARGO_PKG_VERSION", "1.0.6"), ("CARGO_PKG_VERSION_MAJOR", "1"), ("CARGO_PKG_VERSION_MINOR", "0"), ("CARGO_PKG_VERSION_PATCH", "6"), ("CARGO_PKG_VERSION_PRE", ""), ("COLORFGBG", "15;0"), ("COLORTERM", "truecolor"), ("DBUS_SESSION_BUS_ADDRESS", "unix:path=/run/user/1000/bus"), ("DEBUG", "true"), ("DEP_QT_FOUND", "1"), ("DEP_QT_INCLUDE_PATH", "/usr/include/qt"), ("DEP_QT_LIBRARY_PATH", "/usr/lib"), ("DEP_QT_VERSION", "5.15.2"), ("DESKTOP_SESSION", "plasmawayland"), ("DISPLAY", ":1"), ("EDITOR", "nvim"), ("GDK_DPI_SCALE", "1"), ("GDK_SCALE", "1"), ("HOME", "/home/ayush"), ("HOST", "x86_64-unknown-linux-gnu"), ("KDE_APPLICATIONS_AS_SCOPE", "1"), ("KDE_FULL_SESSION", "true"), ("KDE_SESSION_UID", "1000"), ("KDE_SESSION_VERSION", "5"), ("KGLOBALACCELD_PLATFORM", "org.kde.kwin"), ("KONSOLE_DBUS_SERVICE", ":1.76"), ("KONSOLE_DBUS_SESSION", "/Sessions/2"), ("KONSOLE_DBUS_WINDOW", "/Windows/1"), ("KONSOLE_VERSION", "211200"), ("LANG", "en_IN"), ("LANGUAGE", ""), ("LD_LIBRARY_PATH", "/home/ayush/Documents/Programming/Rust/ki18n-rs/target/debug/deps:/home/ayush/Documents/Programming/Rust/ki18n-rs/target/debug:/home/ayush/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib:/home/ayush/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib"), ("LOGNAME", "ayush"), ("MAIL", "/var/spool/mail/ayush"), ("MOTD_SHOWN", "pam"), ("NUM_JOBS", "12"), ("OPT_LEVEL", "0"), ("OUT_DIR", "/home/ayush/Documents/Programming/Rust/ki18n-rs/target/debug/build/ki18n-f4b48303895c005d/out"), ("PAM_KWALLET5_LOGIN", "/run/user/1000/kwallet5.socket"), ("PATH", "/home/ayush/.cargo/bin:/home/ayush/.config/emacs/bin:/usr/local/sbin:/usr/local/bin:/usr/bin:/var/lib/flatpak/exports/bin:/usr/bin/site_perl:/usr/bin/vendor_perl:/usr/bin/core_perl"), ("PLASMA_USE_QT_SCALING", "1"), ("PROFILE", "debug"), ("PROFILEHOME", ""), ("PWD", "/home/ayush/Documents/Programming/Rust/ki18n-rs"), ("QSG_RENDER_LOOP", "basic"), ("QT_AUTO_SCREEN_SCALE_FACTOR", "0"), ("QT_QPA_PLATFORM", "wayland"), ("QT_WAYLAND_FORCE_DPI", "96"), ("RUSTC", "rustc"), ("RUSTDOC", "rustdoc"), ("RUSTUP_HOME", "/home/ayush/.rustup"), ("RUSTUP_TOOLCHAIN", "stable-x86_64-unknown-linux-gnu"), ("RUST_RECURSION_COUNT", "1"), ("SHELL", "/bin/bash"), ("SHELL_SESSION_ID", "5dae93354cfb4c55910afecd99689a4e"), ("SHLVL", "1"), ("SSL_CERT_DIR", "/etc/ssl/certs"), ("SSL_CERT_FILE", "/etc/ssl/cert.pem"), ("SYSTEMD_EXEC_PID", "959"), ("TARGET", "x86_64-unknown-linux-gnu"), ("TERM", "xterm-256color"), ("USER", "ayush"), ("WAYLAND_DISPLAY", "wayland-0"), ("WINDOWID", "1"), ("XAUTHORITY", "/run/user/1000/xauth_AfgCcS"), ("XCURSOR_SIZE", "24"), ("XCURSOR_THEME", "breeze_cursors"), ("XDG_CONFIG_DIRS", "/home/ayush/.config/kdedefaults:/etc/xdg"), ("XDG_CURRENT_DESKTOP", "KDE"), ("XDG_DATA_DIRS", "/home/ayush/.local/share/flatpak/exports/share:/var/lib/flatpak/exports/share:/usr/local/share:/usr/share"), ("XDG_RUNTIME_DIR", "/run/user/1000"), ("XDG_SEAT", "seat0"), ("XDG_SEAT_PATH", "/org/freedesktop/DisplayManager/Seat0"), ("XDG_SESSION_CLASS", "user"), ("XDG_SESSION_DESKTOP", "KDE"), ("XDG_SESSION_ID", "2"), ("XDG_SESSION_PATH", "/org/freedesktop/DisplayManager/Session1"), ("XDG_SESSION_TYPE", "wayland"), ("XDG_VTNR", "2"), ("XKB_DEFAULT_LAYOUT", "us")]

  error occurred: ToolExecError: Command "c++" "-O0" "-ffunction-sections" "-fdata-sections" "-fPIC" "-g" "-fno-omit-frame-pointer" "-m64" "-I" "/home/ayush/Documents/Programming/Rust/ki18n-rs" "-I" "/usr/include/qt" "-I" "/usr/include/qt/QtCore" "-I" "/usr/include/KF5/KI18n" "-Wall" "-Wextra" "-std=c++11" "-o" "/home/ayush/Documents/Programming/Rust/ki18n-rs/target/debug/build/ki18n-f4b48303895c005d/out/rust_cpp/cpp_closures.o" "-c" "/home/ayush/Documents/Programming/Rust/ki18n-rs/target/debug/build/ki18n-f4b48303895c005d/out/rust_cpp/cpp_closures.cpp" with args "c++" did not execute successfully (status code exit status: 1).
ogoffart commented 2 years ago

You can return a KLocalizedString from a function because it's not movable in C++ See https://godbolt.org/z/5Gaqsbnjr

Ayush1325 commented 2 years ago

@ogoffart Ok, so is there a good way to identify an immovable C++ class? The headers for both klocalizedstring and klocalizedtranslator use unique_ptr to store the actual object. Here are the respective field:

  1. klocalizedstring.h
    
    class KLocalizedStringPrivate;

class KI18N_EXPORT KLocalizedString { .... private: std::unique_ptr const d; };


2. klocalizedtranslator.h
```cpp
class KLocalizedTranslatorPrivate;

class KI18N_EXPORT KLocalizedTranslator : public QTranslator
{
......
private:
    std::unique_ptr<KLocalizedTranslatorPrivate> const d;
};
ogoffart commented 2 years ago

I believe QTranslator is the thing that cannot be copied or moved because of Q_DISABLE_COPY. Qt might be keeping pointers to the QTranslator behind the scene.

I'm going to close this issue now since this is not a bug in this crate.

What you have to do is not to use KLocalizedTranslator directuly, but use it by pointer with something like

cpp_class!(
    pub unsafe struct KLocalizedTranslator as "unique_ptr<KLocalizedTranslator>"
);