Marshaling Char *。如何获得所有角色

时间:2011-02-08 12:27:36

标签: .net com marshalling

我正在尝试为自定义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#中声明了这样的界面:

public interface IDumpASF
{

    [PreserveSig]
    int get_UserParams(
        [Out] out int is_auto_start,
        [Out] out int fileSize,
        [Out] out int packetSize,
        [Out] out System.Sbyte baseName,
        [Out] out System.SByte filePath
        );

    [PreserveSig]
    int set_UserParams(
        [In] int is_auto_start,
        [In] int fileSize,
        [In] int packetSize,
        [In] string baseName,
        [In] string filePath
        );

    [PreserveSig]
    int enable_Run([In] bool a);

}

使用的例子如下:

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);

我能够构建和运行soulution,但是我不知道如何获取baseName和filePath的所有字符。当我发送SByte时,它会得到第一个角色,但我该怎么做呢?我尝试了其他几种类型,如Sbyte [],String,StringBuilder和IntPtr。每当我尝试将它们转换为字符串时,我都会遇到AccessViolationException。

我打赌我错过了一些愚蠢的事情,但我的病人在这里穿得很瘦。

任何帮助都会非常受欢迎!

-Svein

2 个答案:

答案 0 :(得分:2)

您必须将参数声明为StringBuilder,不要使用 out 。确保初始化正确传递的字符串构建器,您必须将其容量设置得足够高,以便此本机代码不会破坏垃圾回收堆。修复COM代码需要考虑,因为它基本上是不安全的,它确实应该使用BSTR。

答案 1 :(得分:0)

谢谢你的回答。经过一些试验和错误后,我终于得到了正确的设置。正如你所说,我应该在没有[Out]的情况下使用StringBuilder。我的问题是我得到的价值没有多大意义。除了你告诉我的内容,我还必须指定如何使用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    
   );

-Svein

相关问题