Создание неуправляемой C ++ DLL для замены .NET C # DLL - PullRequest
0 голосов
/ 16 февраля 2012

РЕДАКТИРОВАТЬ: Я решил посмотреть, если была проблема с моим новым DLL, который заставил его вообще не работать.Я создал приложение на C # и добавил свою DLL в качестве ссылки.Когда я сделал это, все работало нормально.Таким образом, кажется, есть проблема с тем, как оно взаимодействует с моим тестовым приложением.

Я работаю над проектом, который включает в себя несколько dll, которые являются сторонними, и у меня нет исходного кода для них.Моя основная ситуация заключается в том, что одна из этих библиотек иногда вызывает функцию в библиотеке, для которой у меня есть исходный код.Моя DLL написана на C #.Однако в настоящее время я заинтересован в замене этого dll на тот, что написан на нативном c ++, так как мне нужно использовать большую библиотеку c ++, и мои потребности не связаны с .NET Framework, 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)
    {
    }
}

Могу ли я создать неуправляемую dll с теми же progid и uuids или мне следует создать стандартную 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;короткий maxCharge = 0;BOOL doChargeState = FALSE;result = m_pUserIDA-> GetChargeStateParam (& minCharge, & maxCharge, & doChargeState);std :: cout << "HRESULT для GetChargeStateParam:" << result << std :: endl; </p>

...