首页 > 解决方案 > 如何创建 C API 到 C++ 函数

问题描述

我正在学习如何在 C++ 中生成随机数数组。我正在使用 std::vector 和 std::generate (我正在尝试使用现代惯用的 C++ - 不确定我做得如何)。

我想做的是将此函数公开给普通的旧 C 代码。如何使这个函数可以从 C 中获得?

代码如下。谢谢!

void RandomArray(std::vector<double> &data)
{
    std::random_device rd{};
    auto mtgen = std::mt19937{ rd() };
    auto ud = std::uniform_int_distribution<>{ 1, 6 };
    auto gen = [&ud, &mtgen](){ return ud(mtgen); };

    std::generate(data.begin(), data.end(), gen);
}

标签: c++cc++14

解决方案


您可以使用该extern "C"语句使函数可链接到C代码。

但是我认为从你的C++版本到C版本更难,它会是这样的:

void RandomArray(std::vector<double> &data)
{
    std::random_device rd{};
    auto mtgen = std::mt19937{ rd() };
    auto ud = std::uniform_int_distribution<>{ 1, 6 };
    auto gen = [&ud, &mtgen](){ return ud(mtgen); };

    std::generate(data.begin(), data.end(), gen);
}

extern "C" void RandomArray(double* data, size_t size)
{
    std::vector<double> v(size);
    RandomArray(v);
    std::copy(std::begin(v), std::end(v), data); // need to copy out
}

就我个人而言,我会采取另一种方式,将C版本作为主要算法并让C++版本调用它:

extern "C" void RandomArray(double* data, size_t size)
{
    std::random_device rd{};
    auto mtgen = std::mt19937{ rd() };
    auto ud = std::uniform_int_distribution<>{ 1, 6 };
    auto gen = [&ud, &mtgen](){ return ud(mtgen); };

    std::generate(data, data + size, gen);
}

void RandomArray(std::vector<double>& data)
{
    RandomArray(data.data(), data.size());
}

此外,每次调用函数时不初始化随机生成器也会快得多。一种方法是制作随机发生器static。如果你需要线程安全,你也可以做到thread_local

extern "C" void RandomArray(double* data, size_t size)
{
    thread_local static auto mtgen = std::mt19937{std::random_device{}()};
    auto ud = std::uniform_int_distribution<>{ 1, 6 };

    std::generate(data, data + size, [&ud](){ return ud(mtgen); });
}

推荐阅读