2012-02-17 94 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