C++ Cli [MarshalAs]属性什么时候生效?

发布于 2024-10-27 17:03:26 字数 758 浏览 1 评论 0原文

如果我以这种方式在 C++ CLI 中声明一个值结构:

  [StructLayout(LayoutKind::Sequential, CharSet = CharSet::Ansi, Pack = 2)]
  value struct TEST
  {
  public:
     UInt32 bla;                                 
     UInt32 foo;                                  
     [MarshalAs(UnmanagedType::ByValTStr, SizeConst = 10)]
     String^ somestring;
     UInt32 bar;                   
  };

并使用该结构,那么该行何时执行 [MarshalAs(UnmanagedType::ByValTStr, SizeConst = 10)] 生效吗? 只有当我调用一些使用 dll import 声明的本机函数或者我手动编组或一直进行时才会有效果吗?

我的问题导致为大型项目中的某些 C# 模块实现本地 C 函数的 C++ Cli 包装器。 如果我做这样的事情:

TEST bla;
pin_ptr<TEST> pinner=&bla;

是否确定,在固定之后,我的结构被包装在一起并且大小为 22 字节(整数为 3*4,字符串为 10)?或者绳子可以再大一点吗?

if I declare a value Struct in C++ CLI in this way:

  [StructLayout(LayoutKind::Sequential, CharSet = CharSet::Ansi, Pack = 2)]
  value struct TEST
  {
  public:
     UInt32 bla;                                 
     UInt32 foo;                                  
     [MarshalAs(UnmanagedType::ByValTStr, SizeConst = 10)]
     String^ somestring;
     UInt32 bar;                   
  };

and use that struct, when does the line
[MarshalAs(UnmanagedType::ByValTStr, SizeConst = 10)]
take effect?
Has it only a effect if I call some native function which is declared with dll import or if I do manually marshalling or the whole time?

My question lead to a implementation of a C++ Cli Wrapper for Native C functions for some C# modules in a large project.
if I do something like this:

TEST bla;
pin_ptr<TEST> pinner=&bla;

Is it certain, that in that moment after pinning my struct is wrapped together and has a size of 22 Byte (3*4 for the integer and 10 for the string)? Or could the string be bigger?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

浪推晚风 2024-11-03 17:03:26

是的,当您调用使用 [DllImport] 属性声明的非托管函数并且该函数具有 TEST 类型的参数时,它就会生效。或者当您使用 Marshal::StructureToPtr 或 Marshal::PtrToStructure 显式编组结构时。它在您的第二个代码段中不会生效。也没有必要使用 pin_ptr<>在那里,bla 变量存储在堆栈中,因此不必固定。

这是您在 C++/CLI 中很少做的事情。因为您已经可以从 .h 文件中获得 TEST 的非托管版本。您只需创建非托管版本并复制成员,这比将其交给 pinvoke 编组器要快得多。但你可以,至少它可以处理字符串。使用 Marshal::StructureToPtr()。

Yes, it takes effect when you make a call to an unmanaged function that you've declared with the [DllImport] attribute and that function has an argument of type TEST. Or when you explicitly marshal the structure with Marshal::StructureToPtr or Marshal::PtrToStructure. It does not take effect in your 2nd snippet. Nor is it necessary to use pin_ptr<> there, the bla variable is stored on the stack so doesn't have to be pinned.

This is something you very rarely ever do in C++/CLI. Since you'd have the unmanaged version of TEST already available from a .h file. You'd simply create that unmanaged version and copy the members, lots faster than leaving it up to the pinvoke marshaller. But you can, at least it takes care of the string. Use Marshal::StructureToPtr().

撕心裂肺的伤痛 2024-11-03 17:03:26

我将回答您问题的一部分:使用 pin_ptr 不会导致编组发生。 pin_ptr 正在锁定托管对象的地址——它不会将其编组到非托管对象。请参阅 http://msdn.microsoft.com/en -us/library/1dz8byfh(v=vs.80).aspx 了解更多详细信息。

I'll answer one part of your question: Using pin_ptr does not cause marshalling to occur. pin_ptr is locking down the address of the managed object--it is not marshalling it to an unmanaged object. See http://msdn.microsoft.com/en-us/library/1dz8byfh(v=vs.80).aspx for more details.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文