C ++ Cli [MarshalAs]属性生效的时刻?

时间:2011-03-30 12:01:00

标签: struct c++-cli marshalling unmanaged value-type

如果我以这种方式在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 ++ Cli Wrapper for Native C函数。 如果我做这样的事情:

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

可以肯定的是,在固定我的结构后的那一刻,它被包裹在一起并且大小为22 Byte(整数为3 * 4,字符串为10)?或者字符串可能更大?

3 个答案:

答案 0 :(得分:3)

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

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

答案 1 :(得分:0)

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

答案 2 :(得分:0)

使用固定大小的缓冲区:How do I specify a fixed-size buffer in C++/CLI?