ATL COM DLL работает с C #, но не с C ++ - PullRequest
1 голос
/ 19 февраля 2012

РЕДАКТИРОВАТЬ: я включил ссылку на код для моей библиотеки ATL COM dll, тестовое приложение и мой оригинальный C # DLL. Поскольку это сложный проект, он может быть самым простым решением. Я довольно отчаянно, так как я не смог найти решение сам. Вот ссылка, если кто-то хочет взглянуть: https://docs.google.com/open?id=0B3ehFEncKJH7ZDgxMGI1YjgtZTE2MS00ZTBkLWI2NzgtYzVhZjUxOWEzZGI0

Я создал dll с помощью ATL и пытался заставить его работать с тестовой программой, которую мне дали. Я не хочу менять способ доступа к dll, поскольку это исправлено. Я основал dll на предыдущей версии C # и попытался сохранить идентификаторы ProgID и UUID одинаковыми.

У меня были проблемы с переполнением буфера, когда я пытаюсь использовать любой из методов. Однако я столкнулся с другой проблемой, и я понятия не имею, почему это происходит. Чтобы убедиться, что моя dll работает, я добавил оператор сна в один из методов. Когда я вызываю этот метод из моей тестовой программы, написанной на неуправляемом c ++, функция сна не работает. Однако, если я создаю приложение на C #, добавляю свою dll в качестве ссылки и вызываю метод, он работает. Кто-нибудь знает, почему это может произойти?

Edit: Я подумал, что мне следует добавить еще некоторые подробности о том, как это используется. Тестовое приложение c ++ создает и экземпляр объекта следующим образом:

IUserIDAPtr m_pUserIDA; 
::CoInitialize(m_pUserIDA);
m_pUserIDA.CreateInstance(_T("Analyst_UserIDA.UserIDAObject"));

if (m_pUserIDA != NULL)
{
    cout << "Aww yeah, that point isn't null" << endl;
    m_pUserIDA->AddRef();


    HRESULT result = m_pUserIDA->OnInitIDA();

прямо сейчас функция сна находится в OnInitIDA.

При использовании C # я добавил ссылку на DLL и сделал это:

        UserIDAObject IDAObject = new UserIDAObject();
        IDAObject.OnInitIDA();
        short minCharge = 0;
        short maxCharge = 0;
        bool doChargeState = false;
        IDAObject.GetChargeStateParam(ref minCharge, ref maxCharge, ref doChargeState);

Когда я пытаюсь использовать GetChargeStatParam в приложении c ++, я получаю переполнение буфера, но это не происходит в версии C #. Но я отвлекся ... В этом случае приложение C # спит в течение 10 секунд.

Я просто не знаю, с чего начать, чтобы понять, почему это не работает.

РЕДАКТИРОВАТЬ: Это интерфейс, который определен в 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);

это реализация OnInitIDA

STDMETHODIMP CUserIDA::OnInitIDA(void)
{
// TODO: Add your implementation code here
Sleep(5000);
return S_OK;
}

Должен ли я беспокоиться о том, как UserIDA определяется в моей dll? Мой предыдущий C # dll, который имел те же методы, работал нормально с этим тестовым приложением.

EDIT: Как ни странно, я обнаружил довольно странное поведение, которое могло бы дать кому-то идею, хотя и озадачивало меня. Я использовал функцию «Step Into» VS2008 и обнаружил, что при вызове OnInitIDA он фактически переходит в другой метод GetInclusionList. Если я добавлю код в этот метод, он будет запущен. Я также думаю, что такое поведение может вызвать переполнение буфера, хотя я не уверен, почему это происходит на самом деле.

1 Ответ

0 голосов
/ 19 февраля 2012

Трудно сказать. Возможно, вы захотите опубликовать код для OnInitIDA.

У вас есть ошибка, которая может или не может быть связана:

Не передавайте ничего CoInitialize. От MSDN :

Параметры

pvReserved [in, optional] 

Этот параметр зарезервирован и должен иметь значение NULL.

...