РЕДАКТИРОВАТЬ: я включил ссылку на код для моей библиотеки 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. Если я добавлю код в этот метод, он будет запущен. Я также думаю, что такое поведение может вызвать переполнение буфера, хотя я не уверен, почему это происходит на самом деле.