我正在尝试为自定义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
答案 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