c – COM interop:如何使用ICustomMarshaler调用第三方组件

c – COM interop:如何使用ICustomMarshaler调用第三方组件,第1张

概述我想使用COM互 *** 作从C#调用COM组件中的方法.这是方法签名: long GetPrecursorInfoFromScanNum(long nScanNumber,LPVARIANT pvarPrecursorInfos,LPLONG pnArraySize) 这是在C中调用它的示例代码(我检查了它真的有用): struct PrecursorInfo{ double dIsola 我想使用COM互 *** 作从C#调用COM组件中的方法.这是方法签名:

long GetPrecursorInfoFromScanNum(long nScanNumber,LPVARIANT pvarPrecursorInfos,LPLONG pnArraySize)

这是在C中调用它的示例代码(我检查了它真的有用):

struct PrecursorInfo{    double disolationMass;    double dMonoIsoMass;    long nChargeState;    long nScanNumber;};voID CTestOCXDlg::OnopenParentScansOcx(){    VARIANT vPrecursorInfos;    Variantinit(&vPrecursorInfos);    long nPrecursorInfos = 0;    m_Rawfile.GetPrecursorInfoFromScanNum(m_nScanNumber,&vPrecursorInfos,&nPrecursorInfos);    // Access the safearray buffer    BYTE* pData;    SafeArrayAccessData(vPrecursorInfos.parray,(voID**)&pData);    for (int i=0; i < nPrecursorInfos; ++i)    {        // copy the scan information from the safearray buffer        PrecursorInfo info;        memcpy(&info,pData + i * sizeof(MS_PrecursorInfo),sizeof(PrecursorInfo));    }    SafeArrayUnaccessData(vPrecursorInfos.parray);}

以下是导入COM组件的类型库后的相应C#签名:

voID GetPrecursorInfoFromScanNum(int nScanNumber,ref object pvarPrecursorInfos,ref int pnArraySize);

如果我没有弄错,我需要为pvarPrecursorInfos传入null,以使COM interop将其编组为预期的VT_EMPTY变体.当我这样做时,我得到一个SafeArrayTypeMismatchException – 并不奇怪,看看如何在样本中处理结果.所以我试图使用自定义封送器.由于a不能改变组件本身,我试着用这种方式介绍它:

[GuID("06F53853-E43C-4F30-9E5F-D1B3668F0C3C")][TypelibType(4160)][Comimport]public interface IInterfaceNew : IInterfaceOrig {    [dispID(130)]    int GetPrecursorInfoFromScanNum(int nScanNumber,[MarshalAs(UnmanagedType.CustomMarshaler,MarshalTypeRef = typeof(MyMarshaler))] ref object pvarPrecursorInfos,ref int pnArraySize);}

TypelibType和dispID属性与原始版本中的相同.这可以调用MyMarshaller.GetInstance()方法,但我没有在MyMarshaller.NativetoManaged中获得回调.而是报告访问冲突.那么这是一种可靠的方法吗?如果是的话 – 我怎样才能让它发挥作用?如果不是:还有其他选择吗?

(只是一个脚注:理论上我可以尝试使用托管C本地调用组件.但是,有很多其他方法可以与COM互 *** 作一起使用,所以我非常希望坚持使用C#,如果有的话无论如何.)

解决方法 由于有人要求,这是我在Managed C中的解决方案.

array<PrecursorInfo^>^ MSfileReaderExt::GetPrecursorInfo(int scanNumber){    VARIANT vPrecursorInfos;    Variantinit(&vPrecursorInfos);    long nPrecursorInfos = -1;    //call the COM component    long rc = pRawfile->GetPrecursorInfoFromScanNum(scanNumber,&nPrecursorInfos);    //read the result    //vPrecursorInfos.parray points to a byte sequence    //that can be seen as array of MS_PrecursorInfo instances    //(MS_PrecursorInfo is a struct defined within the COM component)    MS_PrecursorInfo* pPrecursors;    SafeArrayAccessData(vPrecursorInfos.parray,(voID**)&pPrecursors);    //Now transform into a .NET object     array<PrecursorInfo^>^ infos = gcnew array<PrecursorInfo^>(nPrecursorInfos);    MS_PrecursorInfo currentPrecursor;    for (int i=0; i < nPrecursorInfos; ++i)    {        currentPrecursor = pPrecursors[i];        infos[i] = safe_cast<PrecursorInfo^>(Marshal::PtrToStructure(IntPtr(&currentPrecursor),PrecursorInfo::typeID));    }    SafeArrayUnaccessData(vPrecursorInfos.parray);    return infos;}
总结

以上是内存溢出为你收集整理的c – COM interop:如何使用ICustomMarshaler调用第三方组件全部内容,希望文章能够帮你解决c – COM interop:如何使用ICustomMarshaler调用第三方组件所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/1229984.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-06
下一篇 2022-06-06

发表评论

登录后才能评论

评论列表(0条)

保存