C&C++   发布时间:2022-04-03  发布网站:大佬教程  code.js-code.com
大佬教程收集整理的这篇文章主要介绍了c – COM interop:如何使用ICustomMarshaler调用第三方组件大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
我想使用COR_491_11845@互操作从C#调用COM组件中的方法.这是方法签名:

long GetPrecursorInfoFromScAnnum(long nScannumber,LPVARIANT pvarPrecursorInfos,LPLONG pnArraySizE)

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

struct PrecursorInfo
{
    double disolationR_491_11845@ass;
    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属性与原始版本中的相同.这可以@L_381_0@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;
}
@H_675_38@

大佬总结

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

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

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。