cxx icon indicating copy to clipboard operation
cxx copied to clipboard

Attempting to replicate the PImpl style found in demo, but method not found in UniquePtr<T>

Open EMCP opened this issue 3 years ago • 4 comments

I am quite close to the finish line.. of wrapping a 3rd party C++ library with CXX so I can stop coding C++ and join the Rust hype train.. I am seeing the following error.. it feels like this is just my ignorance of C++ .. that my function signature is not quite matching .. any advice is appreciated

Main.RS

#[cxx::bridge(namespace = "com::enserio")]
mod ffi {
    unsafe extern "C++" {
        include!("twsapi_grpc_server/include/twsapi-client.h");
        include!("twsapi_grpc_server/include/AvailableAlgoParams.h");
        include!("twsapi_grpc_server/include/AccountSummaryTags.h");
        include!("twsapi_grpc_server/include/Utils.h");

        type TWSApiClient;

        fn new_twsapi_client() -> UniquePtr<TWSApiClient>;
        fn connect(self: Pin<&mut TWSApiClient>, port: i32, client_id: i32) -> bool;
    }
}

fn main() {
    let client = ffi::new_twsapi_client();
    client.connect(4002, 333);
}

The Error

error[E0599]: no method named `connect` found for struct `UniquePtr<TWSApiClient>` in the current scope
  --> src/main.rs:21:12
   |
21 |     client.connect(4002, 333);
   |            ^^^^^^^ method not found in `UniquePtr<TWSApiClient>`

For more information about this error, try `rustc --explain E0599`.
error: could not compile `twsapi_grpc_server` due to previous error

TWSAPIClient.cc

...

class TWSApiClient::impl {
    friend TWSApiClient;
};

TWSApiClient::TWSApiClient() : impl(new class TWSApiClient::impl)
        , m_osSignal(2000)//2-seconds timeout
        , m_pClient(new EClientSocket(this, &m_osSignal))
        , m_state(ST_CONNECT) // starts at m_state = 0
        , m_sleepDeadline(0)
        , m_orderId(0)
        , m_extraAuth(false) {}

TWSApiClient::~TWSApiClient()
{
    if( m_pReader ){
        m_pReader.reset();
    }
    delete m_pClient;
}

/**
*  Connect - This part of the client deals with connection to IB Gateway
*
*  See: https://interactivebrokers.github.io/tws-api/classIBApi_1_1EClientSocket.html
*/
    bool TWSApiClient::connect(int port, int clientId) {...}{
    ...

  std::unique_ptr<TWSApiClient> new_twsapi_client() {
    return std::make_unique<TWSApiClient>();
  }

TWSAPIClien.h

class TWSApiClient : public EWrapper {

public:
    #include "EWrapper_prototypes.h"

    TWSApiClient();
    ~TWSApiClient();

    bool connect(int port, int client_id);
    <and many other functions, but first want to just test connecting>

private:
     class impl;
    std::shared_ptr<impl> impl;
    EReaderOSSignal m_osSignal;
    EClientSocket * const m_pClient;
    State m_state;
    time_t m_sleepDeadline;
    OrderId m_orderId;
    std::unique_ptr<EReader> m_pReader;
    bool m_extraAuth;
    std::string m_bboExchange;
    int client_id;
};

std::unique_ptr<TWSApiClient> new_twsapi_client();

EMCP avatar Nov 12 '22 20:11 EMCP

I ran the cargo doc command and can see it has a function called connect under the impl ... but not sure what I am missing

image

EMCP avatar Nov 13 '22 21:11 EMCP

I have modified my conan recipe further.. to explicitly call out my deps.. and everything is working fine still when using just C++ .. but my CXX project still fails to find things.. I don't get it

https://stackoverflow.com/a/74475762/389976 - my modification to my recipe where I call out the system library dep

my conanmanifest.txt

1669456927
bin/JavaDDE.dll: 8a1c959be15a0b8701dbe83338a8f9fa
bin/JavaDDEx64.dll: 4153f04a310ca3610771fc8e35e3c8bc
bin/biddll.dll: 5b6664fa454d750709cfe4b6aff762de
conaninfo.txt: 33600f202dc2ac2783c2a606f6678d2a
include/CommissionReport.h: dc3e59f802e48f98a5d442b3f828fda1
include/CommonDefs.h: 76c431e6b6cf28f85431cf7922b42b62
include/Contract.h: 30f22cc07544fd2927c6d55a0aa8f532
include/ContractCondition.h: 338c06207c139eb50727a405b45711f2
include/Decimal.h: b0ae33c9bd1ba429cdc8b64e837f50de
include/DefaultEWrapper.h: 9ef79c5f2bf05f84f2f6cd71ecf011a9
include/DepthMktDataDescription.h: d152ac5211dfeb932bc0d09a5c68efcc
include/EClient.h: e0b8c74d4799ab1f69b369d455e7d401
include/EClientException.h: 364391057b8d129c5fd3048d04cbd25b
include/EClientMsgSink.h: 039f0d72c18cdfd56f2cc086a192a51c
include/EClientSocket.h: 102edd49f5990a996c6d0a313ecde069
include/EDecoder.h: 230fbc655a959aa710dd81c8a3f02006
include/EMessage.h: 1864a7e06e49bd0900aeb2d540d092d9
include/EMutex.h: 13c65b792e117577f6aa0336080063c0
include/EOrderDecoder.h: 33fb1a5d8c80a1be4f8014b621c9a9dc
include/EPosixClientSocketPlatform.h: 2b4f8e35b523b8c315f8dc10d95f5690
include/EReader.h: bfd2cb150eb1b5ec7d4d0902c50a446f
include/EReaderOSSignal.h: 2646cf85790a77d02393f9601d2bbe6b
include/EReaderSignal.h: 3445b62e82330d96c1d0960c024323fc
include/ESocket.h: 3bf392a921426990e88345f099a0f741
include/ETransport.h: b22da11d30137acaf4cccbbb472cf40c
include/EWrapper.h: 85862b206fc8b39d3b6b025333b24dc6
include/EWrapper_prototypes.h: 72055e8bb6cb53387369e502d3f82937
include/Execution.h: 478a674269396ca20591b92fe21b354f
include/FamilyCode.h: 046882fb077fbff4d78b1dbf995817d4
include/HistogramEntry.h: af34b4f4150a52d02ac4fb55f5b4c154
include/HistoricalSession.h: d72aa4d4789c878d50e1dca8720af7e8
include/HistoricalTick.h: c2ce30d543a14a7f11e2346c2850ec3e
include/HistoricalTickBidAsk.h: 8d8f66466bd6c7df8efa0934ec03fdcc
include/HistoricalTickLast.h: 496d5cf9a17da5c0fbf801e1b8b2a95c
include/IExternalizable.h: 1a2e529c48ba52df4e32419233bdf5a8
include/MarginCondition.h: c61677888e52bed6b50f7d1d45a19754
include/NewsProvider.h: a9f74105139aee84ac5d8afe1a394703
include/OperatorCondition.h: 40f8f0b64dca4e51b363ab6a47de4d81
include/Order.h: 6cbb997c8f5d6769e3000ffdfdfc29b2
include/OrderCondition.h: 08ac57efc6741c2a4f1bc3fe0f2776d9
include/OrderState.h: 7f41dd41f907e004c32976e32b748b95
include/PercentChangeCondition.h: bf5390b73ae673332aedd894923df088
include/PriceCondition.h: 08e42b5739a570fe841f110c8919d93f
include/PriceIncrement.h: 314f7ff3ebfec3f6badd9e44d9373fc8
include/ScannerSubscription.h: ab96323b2f493905ed21390363210d8c
include/SoftDollarTier.h: 448e6a16b69815de1e3e61247e6497fc
include/StdAfx.h: 4c2a04d94745ac8b28cfed549b4254cc
include/TagValue.h: 4b78a41afdad69f0d2fc9915b6d0c8a1
include/TickAttrib.h: 9544d8b0c33549eda8390da1ac196c7e
include/TickAttribBidAsk.h: 1fb4dd1e86e4ff6f4c9827d6954dd96f
include/TickAttribLast.h: 8ace281e3f228bbfe9364755276d193e
include/TimeCondition.h: 4d9557059924f1c7b4cbbbe4d354099f
include/TwsSocketClientErrors.h: fb95ef037bf3f60c86cc0af52e9b05a7
include/VolumeCondition.h: 4190af00ee3e0db634fa42da3a292dbc
include/WshEventData.h: 4688ce2c6c52e3d01fd08b622fdb0650
include/bar.h: ffd367caa980641090a092d7f75e7b2e
include/executioncondition.h: efd9496785ff162315abe48095cd24c7
include/platformspecific.h: afb49774959ec5d8fd045b60f1fba9f2
include/resource.h: f94777f52839d6193582e03ae215fd01
lib/biddll.lib: 35d3c5d1935a045e632f9537a1bf35be
lib/libbid.a: cc99fe8df80f9a360674c91b5023aae0
lib/libbid.lib: 1fa5d341302f79a3a7eb502b27c631c3
lib/libbid.so: e4bd934330ddeb5ba21cf1e08d7cbf19
lib/libtwsapi.a: 3c060cc878f1115e8fe49ef5a02afd1b

and yet the errors persist on cargo build

EMCP avatar Nov 26 '22 10:11 EMCP

I'm running into this exact same issue. Same basic setup and same error. If the demo is modified such that one of the methods is no longer const (requiring the mapping in main.rs to change from &self to self: Pin<&mut BlobstoreClient>) then the demo will show the same error when built.

Is UniquePtr not compatible with opaque C++ types with non-const methods?

arizonatribe avatar Jul 20 '24 06:07 arizonatribe

Looks like there is an answer to this particular challenge (useful especially when you don't control the upstream C++ code) suggested here

I suppose in your case it would mean changing this:

fn main() {
    let client = ffi::new_twsapi_client();
    client.connect(4002, 333);
}

to this:

fn main() {
    let mut client = ffi::new_twsapi_client();
    client.as_mut().unwrap().connect(4002, 333);
}

arizonatribe avatar Jul 20 '24 08:07 arizonatribe

Try this:

fn main() {
    let mut client = ffi::new_twsapi_client();
    client.pin_mut().connect(4002, 333);
}

dtolnay avatar Sep 10 '25 04:09 dtolnay