如何将字节数组作为 UDT 属性从 VB6/VBA 传递到 C# COM DLL?

2024-04-15

我有一个 C# 库,我试图将其公开给 VBA。我可以很好地将参数传递给函数(即“ref byte[] someArray”),但传递对象或结构是行不通的。

如果我尝试将字节数组作为类的属性传递,我会在 VB 中收到以下错误:

函数或接口标记为受限,或者函数使用 Visual Basic 不支持的自动化类型

如果我尝试将字节数组作为结构体的属性传递,我会在 VB 中收到以下错误:

我已经为此奋斗了两天,虽然我不断寻找声称有答案的帖子,但没有一个对我有用。

这是我当前的代码:

[ComVisible(true)]
[Guid("7F53F7A5-15C9-4A99-A855-38F5E87702D0")]
[InterfaceType(ComInterfaceType.InterfaceIsDual)]       // Tried as InterfaceIsDual and as InterfaceIsIDispatch
public interface IDetail
{
    [DispId(1)]     // Tried with and without these
    int SomeInt { get; set; }

    [DispId(2)]
    string SomeString { get; set; }

    [DispId(3)]
    byte[] SomeByteArray { 
        return: MarshalAs(UnmanagedType.SafeArray, SafeArraySubType = VarEnum.VT_UI1)]
        get;
        [param: MarshalAs(UnmanagedType.SafeArray, SafeArraySubType = VarEnum.VT_UI1)]
        set; 
    }
}

[ComVisible(true)]
[Guid("F77FB3D4-27E0-4BFA-A21E-5ACB671151E9")]
[ClassInterface(ClassInterfaceType.None)]
[ProgId("G4COMTest.Detail")]
public class Detail:IDetail
{
    public int SomeInt { get;set; }
    public string SomeString { get; set; }

    // Tried MarshalAs in all combinations of class and interface
    public byte[] SomeByteArray {
        [return: MarshalAs(UnmanagedType.SafeArray, SafeArraySubType = VarEnum.VT_UI1)]
        get; 
        [param: MarshalAs(UnmanagedType.SafeArray, SafeArraySubType = VarEnum.VT_UI1)]
        set;
    }
}

[ComVisible(true)]
[Guid("5E8F9FF0-3156-479E-A91D-0DADD43881FB")]
[ClassInterface(ClassInterfaceType.None)]
public class Worker:IWorker
{
    // works with the 'ref'
    public int ReturnIntWByteArrayParam(ref byte[] testByteArray)
    {
        return testByteArray.Count();
    }

    public int ReturnIntWObjParam(IDetail detail)
    {
        return detail.SomeInt;
    }

    public IDetail ReturnObjNoParams()
    {
        var o = new Detail();
        o.SomeInt = 87;
        o.SomeString = "What are you doing Dave";
        return o;
    }
}

[ComVisible(true)]
[Guid("04962F29-DBBD-48AC-B4FB-180EEF562771")]
[InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
public interface IWorker
{
    int ReturnIntWByteArrayParam(ref byte[] testByteArray);
    int ReturnIntWObjParam(IDetail detail);
    IDetail ReturnObjNoParams();
}

从 VB6 调用它:

Dim o As New G4COMTest.Worker
Dim d As New G4COMTest.Detail
Dim byt(2) As Byte

d.SomeInt = 356                     '// Works
d.SomeString = "Hello from client"  '// Works
d.SomeByteArray = byt               '// Errors as either class or struct
MsgBox mWorker.ReturnIntWObjParam(d)

预先感谢您的任何帮助!


C# 数组属性向 COM 公开一个 getter 和一个 setter,正如您所期望的那样(MarshalAs属性是不必要的,封送拆收器默认情况下会正确检测到它)。

问题在于,与 .NET 中的所有属性设置器一样,设置器也是按值传递值参数。不幸的是,VBA 不支持按值传递数组。这是从一开始就存在的语言的基本限制。更不幸的是,COM 互操作不提供任何使用属性覆盖此行为的方法。你有两个选择:

A - 定义您自己的 setter 方法并从 VBA 调用它而不是属性 setter,例如

void SetSomeByteArray(ref byte[] value) { SomeByteArray = value; }

B - 将属性类型更改为object并使用变体数组而不是强类型数组。

PS:要小心string属性也。这些通常工作得很好,但是如果你通过了null字符串值到VBA,会出错,因为VBAString类型无法存储null参考。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何将字节数组作为 UDT 属性从 VB6/VBA 传递到 C# COM DLL? 的相关文章

  • C++:无法使用scoped_allocator_adaptor传播polymorphic_allocator

    我有一个vector
  • 如何在 Unity 中从 RenderTexture 访问原始数据

    问题的简短版本 我正在尝试访问 Unity 中 RenderTexture 的内容 我一直在使用 Graphics Blit 使用自己的材质进行绘制 Graphics Blit null renderTexture material 我的材
  • 模板类的不明确多重继承

    我有一个真实的情况 可以总结为以下示例 template lt typename ListenerType gt struct Notifier void add listener ListenerType struct TimeListe
  • 在 Xamarin Android 中将图像从 URL 异步加载到 ImageView 中

    我有一个包含多个项目的 ListView 列表中的每个项目都应该有一个与之关联的图像 我创建了一个数组适配器来保存每个列表项并具有我希望加载的图像的 url 我正在尝试使用 Web 请求异步加载图像 并设置图像并在加载后在视图中更新它 但视
  • fgets() 和 Ctrl+D,三次才能结束?

    I don t understand why I need press Ctrl D for three times to send the EOF In addition if I press Enter then it only too
  • Cygwin 下使用 CMake 编译库

    我一直在尝试使用 CMake 来编译 TinyXML 作为一种迷你项目 尝试学习 CMake 作为补充 我试图将其编译成动态库并自行安装 以便它可以工作 到目前为止 我已经设法编译和安装它 但它编译成 dll 和 dll a 让它工作的唯一
  • C# 中值类型和引用类型有什么区别? [复制]

    这个问题在这里已经有答案了 我知道一些差异 值类型存储在堆栈上 而引用类型存储在托管堆上 值类型变量直接包含它们的值 而引用变量仅包含对托管堆上创建的对象位置的引用 我错过了任何其他区别吗 如果是的话 它们是什么 请阅读 堆栈是一个实现细节
  • 跨多个控件共享事件处理程序

    在我用 C 编写的 Windows 窗体应用程序中 我有一堆按钮 当用户的鼠标悬停在按钮上时 我希望按钮的边框发生变化 目前我有以下多个实例 每个按钮一个副本 private void btnStopServer MouseEnter ob
  • 使用 C# 在 WinRT 中获取可用磁盘空间

    DllImport kernel32 dll SetLastError true static extern bool GetDiskFreeSpaceEx string lpDirectoryName out ulong lpFreeBy
  • HttpClient 像浏览器一样请求

    当我通过 HttpClient 类调用网站 www livescore com 时 我总是收到错误 500 可能服务器阻止了来自 HttpClient 的请求 1 还有其他方法可以从网页获取html吗 2 如何设置标题来获取html内容 当
  • Windows 窗体不会在调试模式下显示

    我最近升级到 VS 2012 我有一组在 VS 2010 中编码的 UI 测试 我试图在 VS 2012 中启动它们 我有一个 Windows 窗体 在开始时显示使用 AssemblyInitialize 属性运行测试 我使用此表单允许用户
  • 编译的表达式树会泄漏吗?

    根据我的理解 JIT 代码在程序运行时永远不会从内存中释放 这是否意味着重复调用 Compile 表达式树上会泄漏内存吗 这意味着仅在静态构造函数中编译表达式树或以其他方式缓存它们 这可能不那么简单 正确的 他们可能是GCed Lambda
  • 像“1$”这样的位置参数如何与 printf() 一起使用?

    By man I find printf d width num and printf 2 1 d width num 是等价的 但在我看来 第二种风格应该与以下相同 printf d num width 然而通过测试似乎man是对的 为什
  • 更改窗口的内容 (WPF)

    我创建了一个简单的 WPF 应用程序 它有两个 Windows 用户在第一个窗口中填写一些信息 然后单击 确定 这会将他们带到第二个窗口 这工作正常 但我试图将两个窗口合并到一个窗口中 这样只是内容发生了变化 我设法找到了这个更改窗口内容时
  • C 中的位移位

    如果与有符号整数对应的位模式右移 则 1 vacant bit will be filled by the sign bit 2 vacant bit will be filled by 0 3 The outcome is impleme
  • 可空属性与可空局部变量

    我对以下行为感到困惑Nullable types class TestClass public int value 0 TestClass test new TestClass Now Nullable GetUnderlyingType
  • GDK3/GTK3窗口更新的精确定时

    我有一个使用 GTK 用 C 语言编写的应用程序 尽管该语言对于这个问题可能并不重要 这个应用程序有全屏gtk window与单个gtk drawing area 对于绘图区域 我已经通过注册了一个刻度回调gtk widget add ti
  • 将变量分配给另一个变量,并将一个变量的更改反映到另一个变量中

    是否可以将一个变量分配给另一个变量 并且当您更改第二个变量时 更改会瀑布式下降到第一个变量 像这样 int a 0 int b a b 1 现在 b 和 a 都 1 我问这个问题的原因是因为我有 4 个要跟踪的对象 并且我使用名为 curr
  • 更改显示的 DPI 缩放大小使 Qt 应用程序的字体大小渲染得更大

    我使用 Qt 创建了一些 GUI 应用程序 我的 GUI 应用程序包含按钮和单选按钮等控件 当我运行应用程序时 按钮内的按钮和字体看起来正常 当我将显示器的 DPI 缩放大小从 100 更改为 150 或 200 时 无论分辨率如何 控件的
  • 将 viewbag 从操作控制器传递到部分视图

    我有一个带有部分视图的 mvc 视图 控制器中有一个 ActionResult 方法 它将返回 PartialView 因此 我需要将 ViewBag 数据从 ActionResult 方法传递到 Partial View 这是我的控制器

随机推荐

  • 如何在windows上安装uwsgi?

    我正在尝试在虚拟环境中为 django 项目安装 uwsgi 我使用的是 Windows 10 I did pip install uwsgi我得到了Command python setup py egg info 所以为了解决这个错误 我
  • 收集装置不会注入

    我正在使用 xUnit 2 0收集装置 http xunit github io docs shared context html在许多不同的测试类之间共享公共数据库设置 拆卸 该装置还提供了一些辅助属性 因此我将其注入到每个测试类中 我在
  • 无法将上游映射到 nginx 服务器中的文件夹

    我想将系统端口 82 映射到 127 0 0 1 8080 runningSite 但 nginx 配置出现异常 upstream dev server 127 0 0 1 8080 runningSite server rewrite l
  • ruby 1.9 和 RSpec2 有什么好的突变测试工具吗?

    我曾经使用 Heckle 但由于 ParseTree 的问题 它与 ruby 1 9 不兼容 我一直在寻找替代方案 但唯一看起来有希望的是 Chaser 而且它没有任何明确的文档可供我用来查看是否可以使其与 RSpec 一起使用 它似乎具有
  • 在构造函数中声明属性 Angular 2

    我是一名刚接触 Angular 2 的 java 程序员 在做官方教程时 我很惊讶地发现他们在构造函数中而不是在类的顶部声明了这个属性 我知道 Java 和 JS 有很大不同 但是这样做之间有什么技术原因吗 constructor priv
  • 将图像添加到 R 中的类似表格的输出

    我有一个简单的数据结构 案例是国家 地区 对于每个国家 地区我有几个数字变量 就像这样 dat lt data frame country c Belgium Germany Holland Ireland Var1 1 4 Var2 11
  • 使用 jQuery Validate 插件,如何将错误消息字符串包装在跨度中

    有谁知道如何将内部错误字符串包装在跨度中 我正在为我的表单使用 jQuery Validate 插件 并在标签标记中显示默认的错误消息 这目前还不错 例子
  • 设计 config.timeout_in 不起作用

    我无法使用初始化器 devise rb 中的设计会话超时来使会话超时 I set config timeout in 1 minute 在initializers devise rb 中 我使用一名用户登录并闲置了2 分钟 这假设会使当前会
  • 如何检查当前应用程序进程是否在 Laravel 的队列环境中运行

    我通过特征将全局作用域应用于我的模型 但我不希望在从 Redis 队列调用 处理模型时应用全局作用域 如何检测当前实例是否是队列进程 就像我们有这个 if App environment local The environment is l
  • Android Studio - 无法找到请求目标的有效认证路径

    我收到这个错误 Gradle project name project refresh failed Unable to find valid certification path to requested target 当我在 Andro
  • Where().Count() 和 Count() 之间的区别

    using DBEntities db new DBEntities var employeeAgedAbove30 db Employees Where s gt s Age gt 30 Count Method 1 employeeAg
  • 使用 Sequelize 的多对多关系的简单示例

    我正在尝试使用 Sequelize 构建表之间多对多关系的简单示例 然而 这似乎比我预期的要棘手得多 这是我目前拥有的代码 db js文件导出 Sequelize 连接实例 const Sequelize require sequelize
  • 计算圆形数量级

    对于一个简单的项目 我必须使大数字 例如 4294967123 可读 因此我只写带有前缀的前几个数字 4294967123 gt 4 29G 12345 gt 12 34K 等 代码 简化 如下所示 const char postfixes
  • 从 Cydia 安装调整后重新启动

    我使用 DHowett 的 Theos 对应用程序和 mobilesubstrate 进行了调整 Tweak是应用程序的一个子项目 我在 iPhone 上测试过 一切正常 然后我创建了一个 Cydia 存储库并将我的项目加载到其中 问题是当
  • 未捕获的语法错误:意外的令牌导出

    我用过创建反应应用程序对于我的项目 我收到一个错误 未捕获的语法错误 意外的令牌导出 错误就在这段代码中 export const ENGLISH lang en messages nav translatedMessage Social
  • 使用 Apache Maths 进行多项式回归 (Java)

    有人可以帮我用 Apache Math 库进行多项式回归 2 阶 吗 以下数据应给出此方程 39 79 x 2 497 66 x 997 45 由 Excel 计算 r2 0 9998 coding style from http comm
  • 无法通过 AKS 上的 Azure 流量管理器和 Nginx Ingress 访问服务

    我在两个不同的区域有两个 AKS 集群作为主要集群和辅助集群 我想使用 Azure 流量管理器在主集群和辅助集群上进行基于优先级的端点监控和故障转移机制 我有两个服务 A 和 B 它们在相对路径上路由 服务 a and 服务 b分别 我在每
  • 如何在 python 3 及更高版本中永久删除文件?

    我想永久删除我用 python 代码创建的文件 我知道 os remove 等 但找不到任何特定的内容来永久删除文件 不想用未使用的文件填充垃圾箱 os remove已经是您正在寻找的了 它不会将东西发送到垃圾箱 它只是删除它们
  • 苹果商店拒绝iPhone申请的原因[关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 谁能帮我了解苹果商店拒绝或提出反对提交任何iPhone申请的可能原因 以下是可能的原因 非官方的 从这里 http 10base t co
  • 如何将字节数组作为 UDT 属性从 VB6/VBA 传递到 C# COM DLL?

    我有一个 C 库 我试图将其公开给 VBA 我可以很好地将参数传递给函数 即 ref byte someArray 但传递对象或结构是行不通的 如果我尝试将字节数组作为类的属性传递 我会在 VB 中收到以下错误 函数或接口标记为受限 或者函