【发布时间】:2012-03-09 21:49:07
【问题描述】:
编辑:我已经包含了一个指向我的 ATL COM dll、测试应用程序和我的原始 C# dll 的代码的链接。由于这是一个复杂的项目,它可能是最简单的解决方案。我非常绝望,因为我自己无法找到解决方案。 这是链接,如果有人想看一下: https://docs.google.com/open?id=0B3ehFEncKJH7ZDgxMGI1YjgtZTE2MS00ZTBkLWI2NzgtYzVhZjUxOWEzZGI0
我使用 ATL 创建了一个 dll,并试图让它与给定的测试程序一起工作。我不想更改它访问 dll 的方式,因为这是固定的。我将 dll 基于以前的 C# 版本并尝试保持 ProgID 和 UUID 相同。
当我尝试使用任何方法时,我一直遇到缓冲区溢出问题。但是我遇到了另一个问题,我不知道它为什么会发生。为了确保我的 dll 正常工作,我在其中一种方法中添加了 sleep 语句。当我从用非托管 c++ 编写的测试程序中调用此方法时,睡眠功能似乎不起作用。但是,如果我创建一个 C# 应用程序并将我的 dll 添加为引用并调用它确实有效的方法。有谁知道为什么会发生这种情况?
编辑: 我想我应该包括一些关于如何使用它的更多细节。测试 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);
当我尝试在 c++ 应用程序中使用 GetChargeStatParam 时,出现缓冲区溢出,但在 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;
}
我应该关心如何在我的 dll 中定义 UserIDA 吗?我以前使用相同方法的 C# dll 在这个测试应用程序中运行良好。
编辑: 奇怪的是,我发现了一些相当奇怪的行为,尽管它让我感到困惑,但它们可能会给某人一个想法。我使用了 VS2008 的“Step Into”功能,发现当调用 OnInitIDA 时,它实际上是进入了另一个方法 GetInclusionList。如果我在这个方法中加入一些代码,它就会运行。我也认为这种行为可能会导致缓冲区溢出,尽管我不确定为什么会发生这种情况。
【问题讨论】:
-
你不需要
AddRef你从CreateInstance得到的指针。 -
根据您的编辑,我会说您的 VTABLE 搞砸了。最可能的原因是 C++ 与 C# 端的 IDAObject 接口定义不同。
标签: c++ visual-c++ dll com atl