我正在开发一个项目,涉及许多第三方的dll,我没有它们的源代码。我的基本情况是这些dll中的一个偶尔调用一个dll中的函数,我确实有源代码。我的dll是用C#编写的。但是我目前有兴趣用原生c ++编写的dll替换那个dll,因为我需要使用大型c ++库,而我的需求并不依赖于.NET框架,C#只是原始源代码的语言我是给出。所以我想知道这样做的最佳方式是什么。
这是我的dll片段,显示已定义显示(省略了许多方法):
namespace UserIDA
{
[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);
}
}
[Guid("5B2DBDD4-B763-428a-B48F-2E148138E7A4")]
[ClassInterface(ClassInterfaceType.None)]
[ProgId("UserIDA.UserIDAObject")]
public unsafe class UserIDAObject : IUserIDA
{
const long S_OK = 0;
const long S_FALSE = 1;
public UserIDAObject()
{
}
~UserIDAObject()
{
}
public void GetSwitchCriteria(ref double intensity, ref double minMass, ref double maxMass, ref bool selectIntensity, ref long numOfDepCycles)
{
}
}
我可以使用相同的progid和uuids创建非托管dll,还是应该创建标准c ++ dll并创建托管包装?
修改 所以我试图使用ATL做到这一点,但遇到了一个问题。我实现了界面。当我运行测试应用程序时,我曾经测试过我的原始dll,并尝试调用一些方法,最终生成异常(现在所有的方法都是空的,它只是一个骨架)。如果我调用没有输入参数的OnInitIDA和OnScreenSurveyScan方法,我得到的HRESULT为0.但是在某些情况下我没有得到它。例如,GetChargeStateParam似乎不起作用。我不得不想知道我在界面中添加的定义是否存在不一致或不正确的内容。
这些是我添加到新dll的方法。它们应与上面发布的界面相匹配:
STDMETHOD(GetSwitchCriteria)(DOUBLE* intensity, DOUBLE* minMass, DOUBLE* maxMass, BOOL* selectIntensity, LONG* numOfDepCycles);
STDMETHOD(GetChargeStateParam)(SHORT* minCharge, SHORT* maxCharge, 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, 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);
我刚刚意识到我忘记了包含C#项目的原始界面,以便进行比较。只有OnPrepareNextScan似乎有效。
[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, int itemCount);
用于调用其中一个失败的测试代码是: short minCharge = 0; short maxCharge = 0; BOOL doChargeState = FALSE; result = m_pUserIDA-> GetChargeStateParam(& minCharge,& maxCharge,& doChargeState); std :: cout<< “GetChargeStateParam的HRESULT:”<<结果<<的std :: ENDL;