将数组从托管代码传递到非托管C++ActiveX组件

本文关键字:C++ActiveX 组件 数组 托管代码 | 更新日期: 2023-09-27 17:58:20

在前面的文章中将指针从托管C++/CLI传递到ActiveX C++组件中,我询问了将数组(无论是托管数组还是非托管数组)传递到在本机C++中创建的ActiveX组件的正确方法。activeX方法具有以下签名:

short Component::CopyToBuffer(short FAR* ptr) {}

当导入activeX以在C++/CLI 中使用时

方法签名显示为

short Component::CopyToBuffer(short% ptr) {}

当在C#中导入时,它显示为

short Component::CopyToBuffer(ref short ptr) {}

但是,我无法正确地传递数组。

是否为本机阵列:short* shortsArray = new short[500];

既不是托管阵列:array<short>^ shortsArray = gcnew array<short>(500);

用户ildjarn和Hans-Passant建议我需要编辑interop程序集文件,将导出的方法签名更改为类似Component::(int16[]ptr)的内容,我这样做了,并成功编译了该项目,但遇到了其他类型的问题(类型不匹配或其他问题)。

因此,现在我制作了一个重现问题解决方案的示例项目
该解决方案包含:

  • 在SomeCompCtl.h中找到一个ActiveX组件的项目,该组件具有一个方法CopyToBuffer
  • C++/CLI中的一个测试项目。其中一个表单添加了activeX,一个按钮调用具有给定值数组的方法
  • C#中另一个做同样事情的测试项目

要运行项目,请执行以下操作:-只需编译SomeComp即可生成包含ActiveX的SomeComp.ocx。-regsrv32 ActiveX控件

请注意,我无法访问ActiveX代码(我曾访问过一个版本的代码,但我不能假设开发人员会继续为我提供更新版本的代码),因此任何解决方案都不应依赖于更改ActiveX接口或代码。我通常只有ocx文件及其tlb文件。

将数组从托管代码传递到非托管C++ActiveX组件

签名为CopyToBuffer(short% ptr),您是如何调用它的?如果执行CopyToBuffer(myArray[0])CopyToBuffer(&myArray[0]),则可能会失败,因为垃圾收集器可能会在您身上移动阵列。试试这个:

pin_ptr<short> pinned = &myArray[0];
component->CopyToBuffer(pinned);

如果不起作用,请尝试再次编辑互操作程序集文件,将签名更改为CopyToBuffer(IntPtr ptr)。由于它更明确地说明了参数是一个简单的指针这一事实,也许这会更好地工作。