ATL COM DLL 适用于 C#,但不适用于 C++
编辑:我已经包含了 ATL COM dll、测试应用程序和原始 C# dll 代码的链接。由于这是一个复杂的项目,它可能是最简单的解决方案。我非常绝望,因为我自己无法找到解决方案。 这是链接,如果有人想看的话: https://docs.google.com/open?id=0B3ehFEncKJH7ZDgxMGI1YjgtZTE2MS00ZTBkLWI2NzgtYzVhZjUxOWEzZGI0
我使用 ATL 创建了一个 dll,并试图让它与我提供的测试程序一起工作。我不想改变它访问 dll 的方式,因为这是固定的。我基于以前的 C# 版本构建了 dll,并尝试保持 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();
现在 sleep 函数位于 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;
}
我应该关心 UserIDA 在我的 dll 中是如何定义的吗?我以前的 C# dll 具有相同的方法,在此测试应用程序中运行良好。
编辑: 奇怪的是,我发现了一些相当奇怪的行为,尽管它让我困惑,但可能会给某人一个想法。我使用了VS2008的“Step Into”功能,发现当调用OnInitIDA时,它实际上进入了另一个方法GetInclusionList。如果我在这个方法中放入一些代码,它就会运行。我还想象这种行为可能会导致缓冲区溢出,尽管我不确定为什么会发生这种情况。
EDIT: I have included a link to the code for my ATL COM dll, the test application and my original C# dll. As this is a complex project it might be the easiest solution. I am pretty desperate as I have not been able to find a solution myself.
Here is the link, if anyone wants to take a look:
https://docs.google.com/open?id=0B3ehFEncKJH7ZDgxMGI1YjgtZTE2MS00ZTBkLWI2NzgtYzVhZjUxOWEzZGI0
I created a dll using ATL and was trying to get it to work with a test program I was given. I do not want to change the manner in which it accesses the dll as this is fixed. I based the dll on a previous C# version and tried to keep the ProgIDs and UUIDs the same.
I have been having problems with a buffer overrun when I try to use any of the methods. However I have run into another problem and I have no idea why it is occurring. In order to make sure my dll was working I added a sleep statement to one of the methods. When I call this method from my test program, written in unmanaged c++, the sleep function does not appear to work. However, if I create a C# application and add my dll as a reference and call the method it does work. Does anyone have any idea why this might happen?
Edit:
I thought I should include some more details about how it was being used. The test c++ application creates and instance of the object like this:
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();
right now the sleep function is in OnInitIDA.
When using C# I added a reference to the DLL and did this:
UserIDAObject IDAObject = new UserIDAObject();
IDAObject.OnInitIDA();
short minCharge = 0;
short maxCharge = 0;
bool doChargeState = false;
IDAObject.GetChargeStateParam(ref minCharge, ref maxCharge, ref doChargeState);
When I try to use GetChargeStatParam in the c++ application I get a buffer overrun but this does not happen in the C# version. But I digress...
In this case the C# application sleeps for 10 seconds.
I just do not know where to even begin looking in order to figure out why it does not work.
EDIT: This is the interface that is defined in the 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);
this is the implementation of OnInitIDA
STDMETHODIMP CUserIDA::OnInitIDA(void)
{
// TODO: Add your implementation code here
Sleep(5000);
return S_OK;
}
Should I be concerned about how the UserIDA is defined in my dll? My previous C# dll that had the same methods worked fine with this test application.
EDIT:
Strangely enough I have found some rather strange behaviour that might give someone an idea though it puzzles me. I used the "Step Into" feature of VS2008 and found that when OnInitIDA is called it actually steps into another method GetInclusionList. If I put some code in this method it gets run. I also imagine this kind of behavior could cause a buffer overrun though I am not sure why this is actually happening.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
很难说。您可能想发布 OnInitIDA 的代码。
您确实有一个可能相关或不相关的错误:
不要将任何内容传递给
CoInitialize
。来自 MSDN :Hard to say. You might want to post the code for OnInitIDA.
You do have a bug that may or may not be related:
Don't pass anything to
CoInitialize
. From MSDN :