使用C#互操作,我需要调用第三方C++库中的函数.C++函数需要std::optional个参数:

void FunctionToCall(std::optional<wchar_t const*> arg)

我想我将不得不将std::optional建模为包含一个布尔值和一个指针的 struct .但我没有找到任何关于std::optional的内存布局的信息.内存布局甚至可能是特定于编译器的.因此,以防万一:它看起来像是使用Microsoft VC++编写的C++库.

所以我的问题是:在VC++中,std::optional的内存布局是什么?在这种情况下,如何正确地进行互操作?

推荐答案

使用Cang的pahole工具,这就是结果


class optional<int> : _Optional_base<int, true, true> {
public:
};

struct _Optional_base<int, true, true> : _Optional_base_impl<int, std::_Optional_base<int, true, true> > {
    struct _Optional_payload<int, true, true, true> _M_payload; /*     0     8 */
};

class _Optional_base_impl<int, std::_Optional_base<int, true, true> > {
protected:
};

struct _Optional_payload<int, true, true, true> : _Optional_payload_base<int> {
};

struct _Optional_payload_base<int> {
    union _Storage<int, true>  _M_payload;           /*     0     4 */
    bool                       _M_engaged;           /*     4     1 */
};

union _Storage<int, true> {
    struct _Empty_byte         _M_empty;           /*     0     0 */
    int                        _M_value;           /*     0     4 */
};

struct _Empty_byte {
};

《龙珠》:https://godbolt.org/z/r4KTfYKoW

归根结底这相当于

class optional<int> { 
    int value;
    bool used;
};

Csharp相关问答推荐

如何从顶部提取发票号作为单词发票后的第一个匹配

将修剪声明放入LINQ中

在发布表单时绑定包含附加(嵌套)列表的对象列表的正确语法是什么

使用C#中的SDK在Microsoft Graph API上使用SubscribedSkus的问题

Thad.Sept()vs Task.Delay().Wait()

Take()方法如何与IAsyncEnumerable一起使用

如何将ASP.NET Core 2.1(在.NET框架上运行)更新到较新的版本?

使用C#HttpClient以多部分形式数据发送带有非ASCII文件名的文件的问题

如何从ASP.NET核心MVC视图和Blazor传递数据

C#DateTime.ParseExact不使用特定日期

HttpRequestMessage.SetPolicyExecutionContext不会将上下文传递给策略

将操作从编辑页重定向到带参数的索引页

如何避免在.NET中将日志(log)写入相对路径

RavenDb:为什么在字符串==空的情况下过滤会过滤得太多?

在Visual Studio 2022中查找Xamarin模板时遇到问题

除非首先访问使用的终结点,否则本地API上的终结点不起作用

如果图表S批注包含使用LINQ的具有特定名称的批注,我如何签入C#

为什么INTEGER在通过反射调用时对空对象返回TRUE,而在INTEGER上调用时返回FALSE?

C#LINQ多行条件

从具有泛型类型约束的类继承-Blazor