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

时间:2011-06-02 16:23:24

标签: c# visual-c++ c++-cli interop activex

在早期的帖子Passing pointer from managed C++/CLI to ActiveX C++ component中,我问过将数组(无论是托管数组还是非托管数组)传递给在本机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建议我需要编辑互操作程序集文件,将导出的方法签名更改为Component :: :( int16 [] ptr),我做了并成功编译了项目,但遇到了其他类型的问题(类型不匹配等)。

所以现在我已经制作了一个重现问题解决方案的示例项目 解决方案包含:

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

运行项目: - 只需编译SomeComp即可生成包含ActiveX的Somecomp.ocx。 - regsrv32 ActiveX控件

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

1 个答案:

答案 0 :(得分:0)

签名为CopyToBuffer(short% ptr),您是如何称呼的?如果您执行了CopyToBuffer(myArray[0])CopyToBuffer(&myArray[0]),那可能会失败,因为垃圾收集器可能会在您上面移动数组。试试这个:

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

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