简体   繁体   English

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

[英]Passing an array from managed code to unmanaged C++ ActiveX component

In an earlier post Passing pointer from managed C++/CLI to ActiveX C++ component I've asked about the correct means to pass an array (whether managed or unmanaged array) to an activeX component created in native C++.在之前的一篇文章将指针从托管 C++/CLI 传递到 ActiveX C++ 组件中,我询问了将数组(无论是托管数组还是非托管数组)传递给在本机 C++ 中创建的 activeX 组件的正确方法。 The activeX method has the following signature: activeX 方法具有以下签名:

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

when the activeX is imported to be used in C++/CLI当 ActiveX 被导入以在 C++/CLI 中使用时

the method signature is displayed as方法签名显示为

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

when imported in C# it is displayed as在 C# 中导入时显示为

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

However, I was not able to pass the array correctly.但是,我无法正确传递数组。

whether native array: short* shortsArray = new short[500];是否原生数组: short* shortsArray = new short[500];

neither a managed array: array<short>^ shortsArray = gcnew array<short>(500);既不是托管数组: array<short>^ shortsArray = gcnew array<short>(500);

users ildjarn and Hans Passant suggested that I need to edit the interop assembly file to change the exported method signature to something like Component::(int16[] ptr) which I did and successfully compiled the project but ran into other kind of problems (type mismatch or something).用户 ildjarn 和 Hans Passant 建议我需要编辑互操作程序集文件以将导出的方法签名更改为 Component::(int16[] ptr) 之类的东西,我这样做并成功编译了项目但遇到了其他类型的问题(类型不匹配什么的)。

So now I've made a sample project that reproduces the problemnSolution所以现在我制作了一个重现问题的示例项目
The solution contains:解决方案包含:

  • A project for the ActiveX component with one method CopyToBuffer found in SomeCompCtl.h ActiveX 组件的项目,其中一种方法 CopyToBuffer 在 SomeCompCtl.h 中找到
  • A test project in C++/CLI. C++/CLI 中的测试项目。 with a single form that has the activeX added to it and a button calls the method with an array of given values.使用添加了 activeX 的单个表单和一个按钮调用具有给定值数组的方法。
  • Another test project in C# that does the same thing C# 中的另一个测试项目做同样的事情

To run the project: - Simply compile SomeComp to generate Somecomp.ocx which contains the ActiveX.要运行该项目: - 只需编译 SomeComp 以生成包含 ActiveX 的 Somecomp.ocx。 - regsrv32 the ActiveX control - regsrv32 ActiveX 控件

Please note that I don't access to the ActiveX code (I've had access to one version of code but I cannot presume that the developers will continue to provide me with updated versions of code) so any solutions shouldn't depend on changing the ActiveX interfaces or code.请注意,我无法访问 ActiveX 代码(我可以访问一个版本的代码,但我不能假设开发人员会继续为我提供更新版本的代码),因此任何解决方案都不应依赖于更改ActiveX 接口或代码。 I normally only have the ocx file with its tlb file.我通常只有 ocx 文件及其 tlb 文件。

With the signature as CopyToBuffer(short% ptr) , how did you call it?签名为CopyToBuffer(short% ptr) ,你是怎么称呼它的? If you did CopyToBuffer(myArray[0]) or CopyToBuffer(&myArray[0]) , that could fail because the garbage collector could move the array on you.如果您CopyToBuffer(myArray[0])CopyToBuffer(&myArray[0]) ,则可能会失败,因为垃圾收集器可能会将数组移到您身上。 Try this:尝试这个:

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

If that doesn't work, try editing the interop assembly file again, change the signature to CopyToBuffer(IntPtr ptr) .如果这不起作用,请尝试再次编辑互操作程序集文件,将签名更改为CopyToBuffer(IntPtr ptr) Since it's more explicit about the fact that the parameter is a simple pointer, perhaps that will work better.由于参数是一个简单的指针这一事实更加明确,也许这样会更好。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM