c++ - 使用 void 指针作为 FFI 接口(interface)类型的好处

标签 c++ c ffi

我正在为 C++ 库编写一个简单的包装器。我有以下类型描述成功结果或错误:

template<typename T>
struct Result
{
    T value;
    const char* error;

    static Result<T> FromFunction(std::function<T()> function)
    {
        Result<T> result = {};
        try
        {
            result.value = function();
        }
        catch( cv::Exception& e )
        {
            const char* err_msg = e.what();
            auto len = std::strlen(err_msg);
            auto retained_err = new char[len + 1];
            std::strcpy(retained_err, err_msg);
            result.error = retained_err;
        }
        return result;
    }
};

我使用它:

extern "C" {
   Result<double> foo() {
      ...
      return result;
   }
}

它在 GCC 中工作得很好(这个函数被调用并返回正确的结果),但是,msvc 会因为模板参数作为函数返回类型而感到非常沮丧:

error C2526: 'foo': C linkage function cannot return C++ class 'CResult<double>'

我编写了以下解决方法,它似乎有效,但我不确定公共(public)接口(interface)中的 void*:

void* foo() { {
    return &result;
}

这被认为是一种不好的做法吗?因为我想遵循 DRY 原则,不要写太多或包装器,例如 ResultDouble、ResultInt 等。

最佳答案

不确定MSVC有什么问题,但如果使用输出参数似乎很高兴(至少在MSVC19-RTW上,godbolt上可用的版本)

extern "C" 
{
   void foo( Result<double> * res ) {
      //....
      *res = {};
   }
}

关于c++ - 使用 void 指针作为 FFI 接口(interface)类型的好处,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48448783/

相关文章:

c++ - 如何在 C++ 中将计算分解为两个 double 和一个字符

c - printf 动态长度/大小

c - 可能包含哪些文件?

c - 如何在 C 中返回多维数组元素的索引?

macos - 从 Rust 调用动态链接的 Haskell 代码

c++ - 使用 QEventLoop 调用函数

c++ - 在 C++ 中使用初始化列表初始化数据成员引用

c++ - 重新解释 Actor 转换

haskell - Haskell 的 FFI 上的函数 'free' 似乎不起作用

multithreading - 捕捉 panic !当 Rust 从 C FFI 调用时,没有生成线程