.net 封送字符*。如何获取所有字符

.net 封送字符*。如何获取所有字符,.net,com,marshalling,.net,Com,Marshalling,我正在尝试为自定义COM接口创建.net包装器 在C++中,接口的定义如下: DECLARE_INTERFACE_(IDumpAsf, IUnknown) { STDMETHOD(get_UserParams) (THIS_ int *is_auto_start, int *fileSize, int *packetSize, char *ba

我正在尝试为自定义COM接口创建.net包装器

在C++中,接口的定义如下:

DECLARE_INTERFACE_(IDumpAsf, IUnknown)
{
    STDMETHOD(get_UserParams) (THIS_
                int *is_auto_start,
                int *fileSize,         
                int *packetSize,
                char *baseName, 
                char *filePath
             ) PURE;

    STDMETHOD(set_UserParams) (THIS_
                int is_auto_start,
                int fileSize,          
                int packetSize,
                char *baseName, 
                char *filePath
             ) PURE;

    STDMETHOD(enable_Run) (THIS_
                bool is_run
             ) PURE;
};
我在C#中声明了如下接口:

使用示例如下:

int is_auto_start;
int fileSize;
int packetSize;
SByte baseName;
SByte filePath;

IDumpASF dump = (IDumpASF)asfWriter;

dump.get_UserParams(out is_auto_start, out fileSize, out packetSize, out baseName, out filePath);
我能够构建和运行解决方案,但我不知道如何获取baseName和filePath的所有字符。当我发送SByte时,它将返回第一个字符,但是如何获取其余字符呢?我尝试过其他几种类型,如Sbyte[]、String、StringBuilder和IntPtr。每当我尝试将它们转换为字符串时,都会得到AccessViolationException

我打赌我错过了一些愚蠢的事情,但我的病人在这里越来越瘦了

任何帮助都是非常感激的


-Svein

您必须将参数声明为StringBuilder,不要使用out。确保正确初始化传递的字符串生成器,您必须将其容量设置得足够高,以便本机代码不会破坏垃圾收集堆。固定COM代码将是一件值得考虑的事情,因为它基本上是不安全的,它确实应该使用BSTR。

< P>谢谢您的回答。经过更多的尝试和错误,我终于得到了正确的设置。正如您所说,我应该使用StringBuilder而不使用[Out]。我的问题是,我得到的价值观没有多大意义。除了您告诉我的内容之外,我还必须指定如何使用MarshalAs属性封送值

非常感谢你的帮助

这就是测试类的外观:

System.Text.StringBuilder baseName = new System.Text.StringBuilder(256);
System.Text.StringBuilder filePath = new System.Text.StringBuilder(256);

EncirisWrapper.IDumpASF dump = (EncirisWrapper.IDumpASF)asfWriter;

dump.get_UserParams(out is_auto_start, out fileSize, out packetSize, baseName, filePath);
这就是包装器的外观:

[PreserveSig]
int get_UserParams(
   [Out] out int is_auto_start,
   [Out] out int fileSize,
   [Out] out int packetSize,
   [MarshalAs(UnmanagedType.LPStr)] System.Text.StringBuilder baseName,
   [MarshalAs(UnmanagedType.LPStr)] System.Text.StringBuilder filePath    
   );

-斯文

你好,汉斯。如前所述,我可以使用StringBuilder来实现这一点。我还使用一个SByte数组进行了测试,如果使用Marshallas(UnmanagedType.LPArray),它也可以正常工作。有什么建议吗?@Svein,StringBuilder是标准方式。无需再次将字节[]转换为编码为字符串。默认值。GetString()确定。我想我会选择StringBuilder。谢谢
[PreserveSig]
int get_UserParams(
   [Out] out int is_auto_start,
   [Out] out int fileSize,
   [Out] out int packetSize,
   [MarshalAs(UnmanagedType.LPStr)] System.Text.StringBuilder baseName,
   [MarshalAs(UnmanagedType.LPStr)] System.Text.StringBuilder filePath    
   );