C#向COM公开字节数组

C#向COM公开字节数组,c#,com,interop,C#,Com,Interop,我正在尝试在C#中创建一个COM dll,它有一个byte[]属性表示图像。这个想法是,一个同事正在编写一个C++应用程序,它将使用我的DLL与一个摄像头进行交互。 我的dll成功地允许他的程序连接到相机,返回各种值,但创建的SAFEARRAY似乎无法读取(他获得了长度的数字,但无法读取其实际数据) 我是否做了一些愚蠢的事情,试图以如下所示的方式将图像作为字节数组传递出去 我是否需要显式地告诉VisualStudio使用特定的封送处理类型,而不是允许它自己选择 我是否也应该公开一个指向字节数组的

我正在尝试在C#中创建一个COM dll,它有一个byte[]属性表示图像。这个想法是,一个同事正在编写一个C++应用程序,它将使用我的DLL与一个摄像头进行交互。 我的dll成功地允许他的程序连接到相机,返回各种值,但创建的SAFEARRAY似乎无法读取(他获得了长度的数字,但无法读取其实际数据)

  • 我是否做了一些愚蠢的事情,试图以如下所示的方式将图像作为字节数组传递出去

  • 我是否需要显式地告诉VisualStudio使用特定的封送处理类型,而不是允许它自己选择

  • 我是否也应该公开一个指向字节数组的指针,或者SAFEARRAY结构会处理这个问题

  • 我使用C#才几个月,这是我第一次编写COM dll,如果我遗漏了一些明显的东西,请耐心等待。我一直在假设问题1不是问题,因为单独的C#test应用程序可以成功地重建图像

    课程(节选):

    [ComVisible(true)]
    [ClassInterface(ClassInterfaceType.None)]
    public class ResultInfo : IResult
    {
        public byte[] ImageBytes
        {
            get
            {
                MemoryStream ms = new MemoryStream();
                this.Image.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);
                byte[] returnBytes = ms.ToArray();
                ms.Close();
                return returnBytes;
            }
        }
    }
    
    [ComVisible(true)]
    [InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
    public interface IResult
    {
        [DispId(5)]
        byte[] ImageBytes { get; }
    }
    
    界面(节选):

    [ComVisible(true)]
    [ClassInterface(ClassInterfaceType.None)]
    public class ResultInfo : IResult
    {
        public byte[] ImageBytes
        {
            get
            {
                MemoryStream ms = new MemoryStream();
                this.Image.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);
                byte[] returnBytes = ms.ToArray();
                ms.Close();
                return returnBytes;
            }
        }
    }
    
    [ComVisible(true)]
    [InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
    public interface IResult
    {
        [DispId(5)]
        byte[] ImageBytes { get; }
    }
    
    < > >强>编辑:< /强>这是从C++方面输出的:

    当我尝试使用HRESULT hr访问SAFEARRAY时= 安全阵列访问数据(图像和数据);返回的hr是意外的- SafeArrayAccessData的文档中说这是“安全的” 无法锁定阵列“


    坦率地说,是的,你在做蠢事!;-).NET运行时保留移动数据的权限(包括在代码中声明的字节[C++)将预期数据在一个固定的内存位置。您需要使用一些互操作类来帮助您——也使用“固定”。关键字来阻止垃圾收集器移动关于Hanks Jimmy的数据!我读到这是可能的,但显然没有深入…出于兴趣,为什么其他变量不是这样?其他变量(例如长度)在编组过程中会被复制,因此正确的数据将进入C++。但是,字节[]是对数据的引用,并且你必须使用互操作编组类来帮助你把它移到C++——你还必须担心释放字节数组(可能通过另一个调用到你的COM服务器)。。我建议,除非您有使用COM的要求,否则可能只使用P/Invoke。