将c ++引用的地址传递给指针

时间:2021-02-12 13:29:36

I want to pass a c++ reference to a c style API that only allows pointer arguments for passing custom data.

我想将c ++引用传递给c样式的API,它只允许指针参数传递自定义数据。

In my example i simply cast the address of the c++ reference into a pointer to void (which happens in a function called "function"). This pointer is being passed to a c function (which is called "execute") which also takes a callback function as a parameter. Inside the callback functions implementation (named "callback") i cast the pointer to void back to a pointer to std::vector.

在我的例子中,我只是将c ++引用的地址转换为指向void的指针(在一个名为“function”的函数中发生)。该指针被传递给c函数(称为“execute”),该函数也将回调函数作为参数。在回调函数实现(名为“callback”)中,我将指针void转换回指向std :: vector的指针。

This compiles without warning(s) and error(s) in MS Visual Studio 2017 and runs as desried (the vector "v" contains the numbers from 1 to 5 and they are also printed). However i'm afraid wether this is valid according to the C++ standard.

这在MS Visual Studio 2017中编译时没有警告和错误,并按照需要运行(向量“v”包含从1到5的数字,它们也被打印)。但是,根据C ++标准,我担心这是有效的。

Of course there is the possiblity of using a global std::vector instance. But under some circumstances, as in my case, this might be a bad solution. Because in my case i need an instance of std::vector per call to "function", therefore it's not suitable to have one global instance replacing the parameter. Also global instances might be inappropriate in multithreaded environments, where i want to keep instances of std::vector on the calling stack per thread. Wrapping the std::vector instance by a class and passing a pointer to a std::vector member is also not really what i'm looking for. I'm rather curious about the technical view on the specific implementation i have used.

当然,使用全局std :: vector实例是可能的。但在某些情况下,如我的情况,这可能是一个糟糕的解决方案。因为在我的情况下,每次调用“function”时我需要一个std :: vector实例,因此不适合让一个全局实例替换参数。此外,全局实例在多线程环境中可能不合适,我希望在每个线程的调用堆栈上保留std :: vector的实例。通过类包装std :: vector实例并将指针传递给std :: vector成员也不是我想要的。我对我使用的具体实现的技术观点很好奇。

In a nutshell, would we consider this example a bad practice? Is it valid to take the address of a reference to Type into a pointer to void and cast back from a pointer to void into a pointer to Type while neglecting that the pointee originally was a reference to Type. Are there alternatives instead of the ones i have described above?

简而言之,我们会认为这个例子是一个不好的做法吗?将对Type的引用的地址转换为void的指针并从指向void的指针强制转换为指向Type的指针是有效的,而忽略了指针对象最初是对Type的引用。有替代品而不是我上面描述的那些吗?

Please find the minimal working example below:

请找到下面的最小工作示例:

#include <vector>
#include <iostream>

//
// The API of a 3rd party library (Typical C-Style Interface)
//

void execute(void (*callback)(void *, int[], int), void * context)
{
    int data [5] = {1,2,3,4,5};

    (*callback)(context, data, 5);
}

//
// My callback function fitting the signature for the 3rd party API
//

void callback(void * context, int data [], int size)
{
    std::vector<int> * v = (std::vector<int> *)context;

    for (int i = 0; i < size; i++) {
        v->push_back(data[i]);
    }
}

//
// Pass a reference to an std::vector as void * to the 3rd party API
//

void function(std::vector<int> & v)
{
    execute(callback, (void *)&v);
}

//
// Pass a std::vector as reference to a function
//
// Evaluate the result at the end
//

int main()
{
    std::vector<int> v;

    function(v);

    for (auto & e : v) {
        std::cout << e << std::endl;
    }

    return 0;
}

1 个解决方案

#1


0  

You can't actually do anything with a reference variable except initialize it on definition. Every use of the reference variable after initialization is a direct access to the original variable, what it references.

除了在定义上初始化之外,您无法对引用变量执行任何操作。初始化后每次使用引用变量都是对原始变量的直接访问,它引用的是什么。

In your case, when you do &v in the function function, you don't get the address of the local reference variable v, but the address of the variable v from the main function.

在您的情况下,当您在函数函数中执行&v时,您不会从主函数获取本地引用变量v的地址,而是获取变量v的地址。

In short, this is fine.

简而言之,这很好。

#1


0  

You can't actually do anything with a reference variable except initialize it on definition. Every use of the reference variable after initialization is a direct access to the original variable, what it references.

除了在定义上初始化之外,您无法对引用变量执行任何操作。初始化后每次使用引用变量都是对原始变量的直接访问,它引用的是什么。

In your case, when you do &v in the function function, you don't get the address of the local reference variable v, but the address of the variable v from the main function.

在您的情况下,当您在函数函数中执行&v时,您不会从主函数获取本地引用变量v的地址,而是获取变量v的地址。

In short, this is fine.

简而言之,这很好。