C++/C# HostFXR 通过 std::tuple 传递参数

问题描述 投票:0回答:1

我使用了这个 dotnet 托管示例中的代码并遇到了一些问题。

这就是我获取函数指针的方式:

component_entry_point_fn function = nullptr;
    int rc = functionPointer(
      dllPath.c_str(),
      dotnetType.c_str(),
      methodName.c_str(),
      nullptr,
      nullptr,
      (void**)&function);

然后我称它为:

struct test {
      const char* str = "from host!";
      int i = 1;
    } testArgs;

function(&testArgs, sizeof(testArgs));

而且效果很好。输出:

Hello, world! from Lib [count: 1]
-- message: from host!
-- number: 1
Hello again, world! from Lib [count: 2]
-- message: from host!
-- number: 1

但是当我尝试将参数作为元组传递时:

std::tuple<FunctionArgs...> argsTuple = std::make_tuple(args...);
function(&argsTuple, sizeof(argsTuple));

我明白了:

Hello, world! from Lib [count: 1]
Fatal error. System.AccessViolationException: Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
   at System.SpanHelpers.IndexOfNullByte(Byte*)
   at System.Runtime.InteropServices.Marshal.PtrToStringUTF8(IntPtr)
   at Scripts.Lib.PrintLibArgs(LibArgs)
   at Scripts.Lib.HelloAgain(IntPtr, Int32)

C# 端的代码与上面链接中的示例相同。 另一个重要的事实是,在 Arm MacOS 上一切正常,没有错误。该错误出现在 Linux x86_64 上。编译器到处都是一样的:clang。

结构和元组的 sizeof 相同 - 16 字节。 尝试添加对齐:

alignas(16) std::tuple<FunctionArgs...>
      argsTuple = std::make_tuple(args...);
c# c++ x86-64 host
1个回答
0
投票

gcc 和 clang 似乎都交换了内存中元组元素的顺序 https://godbolt.org/z/PaqaqcqTn,但这是一个实现细节,而不是您可以在代码中依赖的东西。

您不应该跨 C 接口传递 C++ 元组。

© www.soinside.com 2019 - 2024. All rights reserved.