簡體   English   中英

從 shared_ptr 獲取原始指針以將其傳遞給需要原始的 function

[英]Getting raw pointer from shared_ptr to pass it to function that requires raw

好的,首先我對 C++ 很陌生,如果我的理解很差,我深表歉意。 我會盡力解釋自己。 我所擁有的是我正在使用一個返回std::shared_ptr<SomeObject>的庫 function ,然后我有一個不同的庫 function ,它采用原始指針參數(更具體地說是 node-addon-api Napi::External<T>::New(Napi::Env env, T *data) static 函數)。 我想使用我的 std::shared_ptr 創建一個 Napi Napi::External object。 我目前正在做的是這樣的:

{
    // ...
    std::shared_ptr<SomeObject> pSomeObject = something.CreateSomeObject();
    auto ext = Napi::External<SomeObject>::New(info.Env(), pSomeObject.get());
    auto instance = MyNapiObjectWrapper::Create({ ext });
    return instance;
}

但我擔心這會遇到 memory 問題。 我的 pSomeObject 僅存在於當前的 scope 中,所以我想在返回之后應該發生什么,它的引用計數將下降到 0,並且它指向的 SomeObject 實例將被銷毀,因此我將遇到我返回的實例的問題使用這個 object。 但是,我已經能夠從我的實例中運行此代碼並在 SomeObject 上調用函數,所以我想我的理解可能是錯誤的。

我的問題是當給定一個共享指針但由於其他第三方庫的要求我需要處理一個原始指針時我應該怎么做? 向我提出的一個選項是制作 object 的深層副本並創建指向該文件的指針

如果我對此的任何理解是錯誤的,請糾正我,正如我所說,我對 C++ 很陌生。

==============================

編輯:

因此,我的原始帖子信息中缺少有關所有權以及該塊到底是什么的信息。 該塊是我對Napi::ObjectWrap實例的實現的實例方法。 這個實例方法需要返回一個Napi::Object ,它對 node.js 中的調用者可用。 I am using Napi::External as I need to pass a sub type of Napi::Value to the constructor New function when creating the Napi:Object I return, and I need the wrapped SomeObject object in the external which I extract in my MyNapiObjectWrapper像這樣的構造函數:

class MyNapiObjectWrapper
{
private:
    SomeObject* someObject;
    static Napi::FunctionReference constructor; // ignore for now
public:
    static void Init(Napi::Env env) {...}
    MyNapiObjectWrapper(const CallbackInfo& info)
    {
        Napi::Env env = info.Env();
        Napi::HandleScope scope(env);

        // My original code to match the above example
        this->someObject = info[0].As<const Napi::External<SomeObject>>().Data();
    }

    DoSomething()
    {
        this->someObject->DoSomething();
    }
}

從那以后我意識到我可以在創建外部時傳遞共享指針的地址並按如下方式使用它

// modified first sample
{{
    // ...
    std::shared_ptr<SomeObject> pSomeObject = something.CreateSomeObject();
    auto ext = Napi::External<SomeObject>::New(info.Env(), &pSomeObject);
    auto instance = MyNapiObjectWrapper::Create({ ext });
    return instance;
}

// modified second sample
class MyNapiObjectWrapper
{
private:
    std::shared_ptr<SomeObject> someObject;
    static Napi::FunctionReference constructor; // ignore for now
public:
    static void Init(Napi::Env env) {...}
    MyNapiObjectWrapper(const CallbackInfo& info)
    {
        Napi::Env env = info.Env();
        Napi::HandleScope scope(env);

        // My original code to match the above example
        this->someObject = 
            *info[0].As<const Napi::External<std::shared_ptr<SomeObject>>>().Data();
    }

    DoSomething()
    {
        this->someObject->DoSomething();
    }
}

所以現在我傳遞一個指向 shared_ptr 的指針來創建我的Napi::External ,我現在的問題是這樣可以嗎? 就像我在開始時所說的那樣,我是 c++ 的新手,但這似乎有點異味。 但是我通過一些調試對其進行了測試,並且可以看到參考計數 go 上升了,所以我想我很清楚???

這里是文檔的重要部分:

Napi::External 模板 class 實現了使用任意 C++ 數據創建 Napi::Value object 的能力。 對於任意 C++ 數據,用戶有責任管理 memory

所以你需要確保object通過data傳遞給Napi Napi::External Napi::External::New退出,直到Napi Napi::External<T> object被破壞。

因此,您顯示的代碼不正確。

您可以做的是將Finalize回調傳遞給New function:

 static Napi::External Napi::External::New(napi_env env, T* data, Finalizer finalizeCallback);

並使用 lambda function 作為Finalize ,即 lambda 可以通過捕獲將副本保存到稱為共享指針,從而允許共享指針保持活動狀態直到 finalize。

std::shared_ptr<SomeObject> pSomeObject = something.CreateSomeObject();
auto ext = Napi::External<SomeObject>::New(
                  info.Env(), 
                  pSomeObject.get(),
                  [pSomeObject](Env /*env*/, SomeObject* data) {});

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM