将数组从托管代码传递到非托管C ++ ActiveX组件 [英] Passing an array from managed code to unmanaged C++ ActiveX component
问题描述
在较早的文章中将托管C ++ / CLI中的指针传递给ActiveX C ++组件我问过正确的传递方式一个数组(无论是托管还是非托管数组)到在本地C ++中创建的activeX组件。
activeX方法具有以下签名:
short Component :: CopyToBuffer(short FAR * ptr){} $导入activeX以在C ++ / CLI中使用时,b $ b
方法签名显示为
short Component :: CopyToBuffer(short%ptr){} $ b $当在C#中导入时,它显示为
<$ p $ <$> p> short Component :: CopyToBuffer(ref short ptr){}
是否为原生数组: short * shortsArray = new short [500];
既不是管理数组: array< short> ^ shortsArray = gcnew array< short>(500);
users ildjarn和Hans Passant建议我需要编辑interop汇编文件以将导出的方法签名更改为类似Component::( int16 [] ptr)我做了并成功编译该项目,但遇到其他类型的问题(类型不匹配或某事)。
现在我做了一个示例项目,再现问题解决
解决方案包含:
- ActiveX组件的项目,在SomeCompCtl.h中找到一种方法CopyToBuffer
-
- 在C ++ / CLI中的测试项目。
- 另一个C#中的测试项目也是这样做的
运行项目:
- 只需编译SomeComp即可生成包含ActiveX的Somecomp.ocx。
- regsrv32 ActiveX控件
请注意,我不访问ActiveX代码(我已访问一个版本的代码,但我不能假定开发人员将继续为我提供更新版本的代码),所以任何解决方案都不应该依赖于更改ActiveX接口或代码。我通常只有ocx文件及其tlb文件。
签名为 CopyToBuffer %ptr)
,你是怎么叫的?如果你做了 CopyToBuffer(myArray [0])
或 CopyToBuffer(& myArray [0])
因为垃圾回收器可以移动你的数组。尝试此操作:
pin_ptr< short> pinned =& myArray [0];
component-> CopyToBuffer(pinned);
如果这不起作用,请尝试再次编辑互操作程序集文件,将签名更改为 CopyToBuffer(IntPtr ptr)
。因为它更明确的事实,参数是一个简单的指针,也许这将工作更好。
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++. The activeX method has the following signature:
short Component::CopyToBuffer(short FAR* ptr) {}
when the activeX is imported to be used in C++/CLI
the method signature is displayed as
short Component::CopyToBuffer(short% ptr) {}
when imported in C# it is displayed as
short Component::CopyToBuffer(ref short ptr) {}
However, I was not able to pass the array correctly.
whether native array: short* shortsArray = new short[500];
neither a managed array: 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).
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
- A test project in 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.
- Another test project in C# that does the same thing
To run the project: - Simply compile SomeComp to generate Somecomp.ocx which contains the ActiveX. - regsrv32 the ActiveX control
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. I normally only have the ocx file with its tlb file.
With the signature as CopyToBuffer(short% ptr)
, how did you call it? If you did CopyToBuffer(myArray[0])
or CopyToBuffer(&myArray[0])
, that could fail because the garbage collector could move the array on you. 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)
. Since it's more explicit about the fact that the parameter is a simple pointer, perhaps that will work better.
这篇关于将数组从托管代码传递到非托管C ++ ActiveX组件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!