Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Linker error when passing tuple to object constructor #636

Open
sztomi opened this issue Oct 9, 2017 · 7 comments
Open

Linker error when passing tuple to object constructor #636

sztomi opened this issue Oct 9, 2017 · 7 comments

Comments

@sztomi
Copy link
Contributor

sztomi commented Oct 9, 2017

Using the latest release (2.1.5), consider the following code:

#include <iostream>
#include <tuple>

#include <msgpack.hpp>

int main() {
    msgpack::object obj(std::make_tuple(2, "hello", 3.4));
    std::cout << obj << "\n";
    return 0;
}

This code compiles, but does not link:

Undefined symbols for architecture x86_64:
  "msgpack::v1::adaptor::object<std::__1::tuple<int, char const*, double>, void>::operator()(msgpack::v2::object&, std::__1::tuple<int, char const*, double> const&)const", referenced from:
      _main in main.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

If I change the first line to msgpack::object obj(123); it compiles and links correctly. I would expect the tuple to also link correctly.

OS, compiler info:

macOS 10.12.6
Apple LLVM version 8.1.0 (clang-802.0.42)

@redboltz
Copy link
Contributor

@sztomi , std::tuple is mapped to ARRAY. ARRAY requires msgpack::zone.
See https://github.com/msgpack/msgpack-c/wiki/v2_0_cpp_object

So, you can use msgpack::object with msgpack::zone as follows:
https://wandbox.org/permlink/a4V243pj4WYDAuyX

I think that compile error is better than link error, but so far, it makes link error.

@sztomi
Copy link
Contributor Author

sztomi commented Oct 18, 2017

Can I use zone with the pack function?

@sztomi
Copy link
Contributor Author

sztomi commented Oct 18, 2017

To shed some light on what I'm trying to do:

This is a function that produces a msgpack::unpacked for use in unit tests. I know it's not efficient, but that's not a problem for unit tests. This used to work with older versions, but now that I'm upgrading, I'm getting a linker error.

template <typename... Types>
inline msgpack::unpacked make_unpacked(Types... items) {
    auto obj = std::make_tuple(items...);
    msgpack::sbuffer buf;
    msgpack::pack(buf, obj);
    return msgpack::unpack(buf.data(), buf.size());
}

// called as:

    auto o = make_unpacked(3, 42, "foo", "bar");

This used to work with older versions, but now that I'm upgrading, I'm getting a linker error. How can I safely make an unpacked out of a tuple?

@redboltz
Copy link
Contributor

I think that your code should work.
See
https://wandbox.org/permlink/56ZuoHJ1Nb7JRK3i

@sztomi
Copy link
Contributor Author

sztomi commented Oct 18, 2017

You are right. Sorry, linker errors are confusing sometimes. My actual error:

"std::__1::enable_if<!(is_array<msgpack::v1::type::nil_t>::value), void>::type msgpack::v1::operator<<<msgpack::v1::type::nil_t>(msgpack::v2::object&, msgpack::v1::type::nil_t const&)", referenced from:
      msgpack::v1::adaptor::object_with_zone<msgpack::v1::type::nil_t, void>::operator()(msgpack::v1::object::with_zone&, msgpack::v1::type::nil_t) const in dispatcher_test.cc.o
      msgpack::v2::object::object<msgpack::v1::type::nil_t>(msgpack::v1::type::nil_t const&) in librpc.a(response.cc.o)
  "void msgpack::v1::operator<<<char, 4ul>(msgpack::v2::object&, char const (&) [4ul])", referenced from:
      msgpack::v2::object::object<char [4]>(char const (&) [4]) in response_test.cc.o

And the code that uses it:

    auto o = make_unpacked(3, 42, "foo", "bar");
    response r(std::move(o));

And that constructor:

    using response_type =
        std::tuple<uint32_t, uint32_t, msgpack::object, msgpack::object>;

response::response(msgpack::object_handle o) : response() {
    response_type r;
    o.get().convert(r);
    id_ = std::get<1>(r);
    auto &&error_obj = std::get<2>(r);
    if (error_obj != msgpack::type::nil_t()) {
        error_ = std::make_shared<msgpack::object_handle>();
        error_->set(msgpack::clone(error_obj).get());
    }
    result_ = std::make_shared<msgpack::object_handle>(
        std::get<3>(r), std::move(o.zone()));
}

When upgrading, I had to change convert(&r) to convert(r) and error_->assign(msgpack::clone(error_obj)) was changed to error_->set(msgpack::clone(error_obj).get());

Any clue what could cause the linker error? The make_unpacked function did not change.

@redboltz
Copy link
Contributor

redboltz commented Oct 18, 2017

I don't understand the code above. Could you show me a minimal and complete code that reproduces the error?

If

#include <iostream>
#include <tuple>

#include <msgpack.hpp>

int main() {
    msgpack::object obj(std::make_tuple(2, "hello", 3.4));
    std::cout << obj << "\n";
    return 0;
}

is so, you can use zone as I mentioned.

@d223chen
Copy link

d223chen commented May 30, 2018

I had a similar issue when trying to create a msgpack::object with a Struct for which I had an adaptor.

My initialization was initially like:
msgpack::object obj(myClass()).

After adding the zone argument, like so

   #include <iostream>
   #include <tuple>
   #include <string>

   #include <msgpack.hpp>

   class myClass{
     int typeId;
     std::string header;
     int timestamp;
     MSGPACK_DEFINE(typeId, header, timestamp); //value array
   };

   int main() {
     msgpack::zone z;
     msgpack::object obj(myClass(), z);
     std::cout << obj << "\n";
     return 0;
   }

it worked!

I had a similar linker error to sztomi which made debugging it really difficult. Of course from the documentation for msgpack::object it is clear that a zone must be used with a complex object type (since we are not using a msgpack::object_handle and thus must be responsible for the memory management).

Perhaps this can be investigated further on the topic of issuing a better compiler error?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants