2012-02-17 308 views
0

我想创建一个使用ATL的COM DLL,与我原来在C#中使用的另一个相匹配。这个DLL通常由第三方DLL调用,我没有源代码,所以我希望UUID和progID一样。我也有一个测试应用程序,它调用我的dll中的方法,这就是我一直在测试它的方法。由测试应用程序定义的接口是:在ATL COM DLL的缓冲区溢出

STDMETHOD(GetSwitchCriteria)(double* intensity, double* minMass, double* maxMass, 
    BOOL* selectIntensity, long* numOfDepCycles) = 0; 
STDMETHOD(GetChargeStateParam)(short* minCharge, short* maxCharge, BOOL* doChargeState) = 0; 
STDMETHOD(GetInclusionList)(double* intensity, double* theList, short* numOfItems) = 0; 
STDMETHOD(GetExclusionList)(long* exRTWindow, double* theMassList, long* theRTList, 
    short* numOfItems) = 0; 
STDMETHOD(GetOtherCriteria)(long* smartFilterTime, double* isoExclusionWin, 
    double* massTolerance, BOOL* isPPM) = 0; 
STDMETHOD(GetIsotopeMatchParam)(double* theMassList, double* theAbundanceList, 
    short* numOfItems, double* abTolerance, double* maTolerance) = 0; 

// called at the start of each IDA run 
STDMETHOD(OnInitIDA)() = 0; 
// called at the end of each survey scan 
STDMETHOD(OnScreenSurveySpec)() = 0; 
// called at the time of switch 
STDMETHOD(OnPrepareNextScan)(double* selectedMasses, double* selectedIntensities, long* selectedCharges, int itemCount) = 0; 

在我的新的DLL使用ATL我试图模仿这和定义如下:

STDMETHOD(GetSwitchCriteria)(DOUBLE* intensity, DOUBLE* minMass, DOUBLE* maxMass, VARIANT_BOOL* selectIntensity, LONG* numOfDepCycles); 
STDMETHOD(GetChargeStateParam)(SHORT* minCharge, SHORT* maxCharge, VARIANT_BOOL* doChargeState); 
STDMETHOD(GetInclusionList)(DOUBLE* intensity, DOUBLE* theList, SHORT* numOfItems); 
STDMETHOD(GetExclusionList)(LONG* exRTWindow, DOUBLE* theMassList, LONG* theRTList, SHORT* numOfItems); 
STDMETHOD(GetOtherCriteria)(LONG* smartFilterTime, DOUBLE* isoExclusionWin, DOUBLE* massTolerance, VARIANT_BOOL* isPPM); 
STDMETHOD(GetIsotopeMatchParam)(DOUBLE* theMassList, DOUBLE* theAbundanceList, DOUBLE* abTolerance, DOUBLE* maTolerance); 
STDMETHOD(OnInitIDA)(void); 
STDMETHOD(OnScreenSurveySpec)(void); 
STDMETHOD(OnPrepareNextScan)(DOUBLE* selectedMasses, DOUBLE* selectedIntensities, LONG* selectedCharges, LONG itemCount); 

我原本用来BOOL的一些参数但我注意到,当我查看TLB文件时,C#dll使用了VARIANT_BOOL。

当我调用两个没有参数的方法时,我得到一个0的HRESULT。OnPrepareNextScan方法也一样。然而,当我打电话给其他人时,我得到一个异常,一个缓冲区溢出,我不知道为什么会出现这种情况。有没有人有一个想法,为什么发生这种情况,或者我可以如何调查?

这是否可能是由于在两个接口中定义的类型之间的类型不兼容以及可能在创建用于该方法的变量时使用的类型?用来调用的方法之一的代码的一个例子是:

​​

尝试以下提到的LONGLONG解决方案,但它似乎并没有帮助。

我以为我应该从C#dll发布原始接口。

[Guid("76F452FF-7A89-11d4-8A2C-00B0D023C6A0")] 
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] 
public unsafe interface IUserIDA 
{ 
    [DispId(1)] 
    void GetSwitchCriteria(ref double intensity, ref double minMass, ref double maxMass, ref bool selectIntensity, ref long numOfDepCycles); 

    [DispId(2)] 
    void GetChargeStateParam(ref short minCharge, ref short maxCharge, ref bool doChargeState); 

    [DispId(3)] 
    void GetInclusionList(ref double intensity, ref double theList, ref short numOfItems); 

    [DispId(4)] 
    void GetExclusionList(ref long exRTWindow, ref double theMassList, ref long theRTList, ref short numOfItems); 

    [DispId(5)] 
    void GetOtherCriteria(ref long smartFilterTime, ref double isoExclusionWin, ref double massTolerance, ref bool isPPM); 

    [DispId(6)] 
    void GetIsotopeMatchParam(ref double theMassList, ref double theAbundanceList, ref short numOfItems, ref double abTolerance, ref double maTolerance); 

    [DispId(7)] 
    void OnInitIDA(); 

    [DispId(8)] 
    void OnScreenSurveySpec(); 

    [DispId(9)] 
    void OnPrepareNextScan(double* selectedMasses, double* SelectedIntensities, long* selectedCharges, int itemCount); 
} 

的最后一个方法,OnPrepareNextScan是,似乎工作只有一个,你可以看到它使用正常的指针,而不是.NET裁判陈述definted,可这是一个问题吗?

我想我可能还包括IIb型文件每个,也许在这些差异会清楚是什么问题,以及两者之间的任何差别:

原来的C#DLL:

// Generated .IDL file (by the OLE/COM Object Viewer) 
// 
// typelib filename: AnalystIDA.dll 

[ 
uuid(7ED40FB0-D178-47FA-9EF3-B434E0803D5F), 
version(1.0), 
custom(90883F05-3D28-11D2-8F17-00A0C9A6186D, "Analyst_UserIDA, Version=1.0.0.0,  Culture=neutral, PublicKeyToken=de4cf4f15e545467") 

] 
library Analyst_UserIDA 
{ 
// TLib :  // TLib : mscorlib.dll : {BED7F4EA-1A96-11D2-8F08-00A0C9A6186D} 
importlib("mscorlib.tlb"); 
// TLib : OLE Automation : {00020430-0000-0000-C000-000000000046} 
importlib("stdole2.tlb"); 

// Forward declare all types defined in this typelib 
interface IUserIDA; 
interface _Utility; 

[ 
    uuid(CDD947DD-7B9E-382E-9F6F-55218F927C3A), 
    version(1.0), 
    custom(0F21F359-AB84-41E8-9A78-36D110E6D2F9, "Analyst_UserIDA.Utility") 
] 
coclass Utility { 
    [default] interface _Utility; 
    interface _Object; 
}; 

[ 
    odl, 
    uuid(76F452FF-7A89-11D4-8A2C-00B0D023C6A0), 
    version(1.0), 
    oleautomation, 
    custom(0F21F359-AB84-41E8-9A78-36D110E6D2F9, "Analyst_UserIDA.IUserIDA")  

] 
interface IUserIDA : IUnknown { 
    HRESULT _stdcall GetSwitchCriteria(
        [in, out] double* intensity, 
        [in, out] double* minMass, 
        [in, out] double* maxMass, 
        [in, out] VARIANT_BOOL* selectIntensity, 
        [in, out] int64* numOfDepCycles); 
    HRESULT _stdcall GetChargeStateParam(
        [in, out] short* minCharge, 
        [in, out] short* maxCharge, 
        [in, out] VARIANT_BOOL* doChargeState); 
    HRESULT _stdcall GetInclusionList(
        [in, out] double* intensity, 
        [in, out] double* theList, 
        [in, out] short* numOfItems); 
    HRESULT _stdcall GetExclusionList(
        [in, out] int64* exRTWindow, 
        [in, out] double* theMassList, 
        [in, out] int64* theRTList, 
        [in, out] short* numOfItems); 
    HRESULT _stdcall GetOtherCriteria(
        [in, out] int64* smartFilterTime, 
        [in, out] double* isoExclusionWin, 
        [in, out] double* massTolerance, 
        [in, out] VARIANT_BOOL* isPPM); 
    HRESULT _stdcall GetIsotopeMatchParam(
        [in, out] double* theMassList, 
        [in, out] double* theAbundanceList, 
        [in, out] short* numOfItems, 
        [in, out] double* abTolerance, 
        [in, out] double* maTolerance); 
    HRESULT _stdcall OnInitIDA(); 
    HRESULT _stdcall OnScreenSurveySpec(); 
    HRESULT _stdcall OnPrepareNextScan(
        [in, out] double* selectedMasses, 
        [in, out] double* SelectedIntensities, 
        [in, out] int64* selectedCharges, 
        [in] long itemCount); 
}; 

[ 
    uuid(5B2DBDD4-B763-428A-B48F-2E148138E7A4), 
    version(1.0), 
    custom(0F21F359-AB84-41E8-9A78-36D110E6D2F9, "Analyst_UserIDA.UserIDAObject") 
] 
coclass UserIDAObject { 
    interface _Object; 
    [default] interface IUserIDA; 
}; 

[ 
    odl, 
    uuid(8094073C-362D-37BB-9791-E9D163271C73), 
    hidden, 
    dual, 
    oleautomation, 
    custom(0F21F359-AB84-41E8-9A78-36D110E6D2F9, "Analyst_UserIDA.Utility")  

] 
interface _Utility : IDispatch { 
}; 
}; 

我的新的DLL:

// Generated .IDL file (by the OLE/COM Object Viewer) 
// 
// typelib filename: AnalystIDA.dll 

[ 
uuid(7ED40FB0-D178-47FA-9EF3-B434E0803D5F), 
version(1.0), 
helpstring("AnalystIDA 1.0 Type Library"), 
custom(DE77BA64-517C-11D1-A2DA-0000F8773CE9, 117441012), 
custom(DE77BA63-517C-11D1-A2DA-0000F8773CE9, 1329510523), 
custom(DE77BA65-517C-11D1-A2DA-0000F8773CE9, "Created by MIDL version 7.00.0500 at Fri  Feb 17 15:28:38 2012 
") 

] 
library AnalystIDALib 
{ 
// TLib :  // TLib : OLE Automation : {00020430-0000-0000-C000-000000000046} 
importlib("stdole2.tlb"); 

// Forward declare all types defined in this typelib 
interface IUserIDA; 

[ 
    uuid(5B2DBDD4-B763-428A-B48F-2E148138E7A4), 
    helpstring("UserIDAObject Class") 
] 
coclass UserIDAObject { 
    [default] interface IUserIDA; 
}; 

[ 
    odl, 
    uuid(76F452FF-7A89-11D4-8A2C-00B0D023C6A0), 
    helpstring("IUserIDA Interface"), 
    dual, 
    nonextensible, 
    oleautomation 
] 
interface IUserIDA : IDispatch { 
    [id(0x00000001), helpstring("method GetSwitchCriteria")] 
    HRESULT GetSwitchCriteria(
        [in, out] double* intensity, 
        [in, out] double* minMass, 
        [in, out] double* maxMass, 
        [in, out] VARIANT_BOOL* selectIntensity, 
        [in, out] long* numOfDepCycles); 
    [id(0x00000002), helpstring("method GetChargeStateParam")] 
    HRESULT GetChargeStateParam(
        [in, out] short* minCharge, 
        [in, out] short* maxCharge, 
        [in, out] VARIANT_BOOL* doChargeState); 
    [id(0x00000003), helpstring("method GetInclusionList")] 
    HRESULT GetInclusionList(
        [in, out] double* intensity, 
        [in, out] double* theList, 
        [in, out] short* numOfItems); 
    [id(0x00000004), helpstring("method GetExclusionList")] 
    HRESULT GetExclusionList(
        [in, out] long* exRTWindow, 
        [in, out] double* theMassList, 
        [in, out] long* theRTList, 
        [in, out] short* numOfItems); 
    [id(0x00000005), helpstring("method GetOtherCriteria")] 
    HRESULT GetOtherCriteria(
        [in, out] long* smartFilterTime, 
        [in, out] double* isoExclusionWin, 
        [in, out] double* massTolerance, 
        [in, out] VARIANT_BOOL* isPPM); 
    [id(0x00000006), helpstring("method GetIsotopeMatchParam")] 
    HRESULT GetIsotopeMatchParam(
        [in, out] double* theMassList, 
        [in, out] double* theAbundanceList, 
        [in, out] double* abTolerance, 
        [in, out] double* maTolerance); 
    [id(0x00000007), helpstring("method OnInitIDA")] 
    HRESULT OnInitIDA(); 
    [id(0x00000008), helpstring("method OnScreenSurveySpec")] 
    HRESULT OnScreenSurveySpec(); 
    [id(0x00000009), helpstring("method OnPrepareNextScan")] 
    HRESULT OnPrepareNextScan(
        [in, out] double* selectedMasses, 
        [in, out] double* selectedIntensities, 
        [in, out] long* selectedCharges, 
        [in] long itemCount); 
}; 
}; 

另一个编辑: 我注意到, ProgID Analyst_UserIDA.UserIDAObject不会出现在我的新dll的类型库中。这用于在测试应用程序中创建UserIDAObject的实例: IUserIDAPtr m_pUserIDA; :: CoInitialize(m_pUserIDA); m_pUserIDA.CreateInstance(_T(“Analyst_UserIDA.UserIDAObject”));

更多进展/困惑: 我决定去看看是否有与DLL中的问题,通过创建一个C#项目,会调用这个DLL。当我这样做时,我遇到了一些工作上的问题。我也注意到,似乎最初起作用的方法不是。我向其中的一个添加了睡眠声明,并且当我的测试应用程序调用它时,它似乎从不会执行。

回答

0

请注意,在Win32中,LONG是一个32位整数,而在C#中,long是一个64位整数。这可能会导致你描述的问题。

每当C#使用long时,解决方法是使用__int64LONGLONG

+0

我会试一试。我正在看这个,但是我发现了很不一致的答案,并且有点困惑。 – Travis 2012-02-17 19:49:33