C++ 为什么我的C和C++;DLL表现出不同的行为?
我正在从事一个项目,该项目涉及创建一个dll,该dll支持某个接口,以便插入某些软件,以便向其添加功能。这是由调用我的dll的dll完成的(我没有进行调用的dll的源代码)。最初,我得到了一个接口和一个C#实现,它创建了一个COM可见dll。然而,在使用了一段时间后,我发现我想利用一些大型C++库,而创建包装器需要花费很长时间来考虑创建一个C++ ATL COM DLL。我这样做了,我的类的方法似乎被正确调用(我注册了我的dll,运行了程序,这些方法似乎被正确的顺序调用),但是我发现有些行为是不同的 我不知道该如何解释这一点,因为我的代码涉及到一个封闭源代码的API,但如果我描述一个示例,可能有人会对我可能想看的地方有一些想法 例如,在C#dll中,我尝试通过以下操作打开一个文件:C++ 为什么我的C和C++;DLL表现出不同的行为?,c++,visual-c++,dll,com,atl,C++,Visual C++,Dll,Com,Atl,我正在从事一个项目,该项目涉及创建一个dll,该dll支持某个接口,以便插入某些软件,以便向其添加功能。这是由调用我的dll的dll完成的(我没有进行调用的dll的源代码)。最初,我得到了一个接口和一个C#实现,它创建了一个COM可见dll。然而,在使用了一段时间后,我发现我想利用一些大型C++库,而创建包装器需要花费很长时间来考虑创建一个C++ ATL COM DLL。我这样做了,我的类的方法似乎被正确调用(我注册了我的dll,运行了程序,这些方法似乎被正确的顺序调用),但是我发现有些行为是不
FMANFileControl fileControl = new FMANFileControl();
FMANFile wFile = null;
const string filePath = @"C:\Data\April 4\Data_IDA.wiff";
wFile = fileControl.GetFileObject(filePath, 1);
long numSamples = wFile.GetNumberOfSamples();
我得到了正确数量的样品
在我的C++ DLL中,我有这个(用一些HEST检查程序删除,以便使代码更短):
但是文件没有正确打开,结果是零样本 我使用oleview查看了typelib,它对函数说:[id(0x00000001), helpstring("method GetWiffFileObject")]
IFMANWiffFile* GetWiffFileObject( [in] BSTR WiffFileName, [in] long sample);
我从中获取信息的文件是在实验期间写入的文件,在它获取更多数据之前,它调用了我的方法,我应该能够获取最新的文件。在C++的DLL中,这是可能的,但是在C++ DLL中,这不是。虽然我意识到了这一点的细节,但我想知道,有没有人知道为什么使用同一个接口的C++ COM DLL和C语言可编辑DLL在被相同的DLL调用时会表现出不同的行为。
我现在很困惑,所以任何想法都会得到赞赏,即使它们被证明是非常离谱的。如果有人认为他们能提供帮助,我可以分享我的源代码
编辑:
我尝试了答案1的解决方案,但是我无法编译我的代码。读到这篇文章时,我发现了这篇文章:
这似乎表明,由于FMANFile指针被标记为[out,retval],因此该方法变为:
IFMANFilePtr ExploreData::IFMANFileControl(BSTR filename, long sample);
还是我误解了那篇文章
编辑2:
虽然我不知道为什么,但它还是起作用了。
最初,我在标题中将变量声明为类的私有成员变量,如下所示:
class ATL_NO_VTABLE CUserIDA :
public CComObjectRootEx<CComSingleThreadModel>,
public CComCoClass<CUserIDA, &CLSID_UserIDAObject>,
public IUserIDA
{
.
.
.
public:
STDMETHOD(GetSwitchCriteria)(DOUBLE* intensity, DOUBLE* minMass, DOUBLE* maxMass, VARIANT_BOOL *selectIntensity, LONG* numOfDepCycles);
.
.
.
private:
ExploreDataObjects::IFMANWiffFilePtr ipFMANWiffFile;
ExploreDataObjects::IFMANWiffFile2Ptr ipFMANWiffFile2;
};
class ATL_NO_VTABLE CUserIDA :
public CComObjectRootEx<CComSingleThreadModel>,
public CComCoClass<CUserIDA, &CLSID_UserIDAObject>,
public IUserIDA
{
ExploreDataObjects::IFMANWiffFilePtr ipFMANWiffFile;
ExploreDataObjects::IFMANWiffFile2Ptr ipFMANWiffFile2;
class ATL\u NO\u VTABLE CUserIDA:
公共CComObjectRootEx,
公共课程,
公共IUserIDA
{
.
.
.
公众:
STDMETHOD(GetSwitchCriteria)(双*强度、双*最小质量、双*最大质量、变量\布尔*选择强度、长*numdepCycles);
.
.
.
私人:
ExploreDataObjects::IFMANWiffFilePtr ipFMANWiffFile;
ExploreDataObjects::IFMANWiffFile2Ptr ipFMANWiffFile2;
};
为了尝试,我将它们移到了类delcaration的顶部,如下所示:
class ATL_NO_VTABLE CUserIDA :
public CComObjectRootEx<CComSingleThreadModel>,
public CComCoClass<CUserIDA, &CLSID_UserIDAObject>,
public IUserIDA
{
.
.
.
public:
STDMETHOD(GetSwitchCriteria)(DOUBLE* intensity, DOUBLE* minMass, DOUBLE* maxMass, VARIANT_BOOL *selectIntensity, LONG* numOfDepCycles);
.
.
.
private:
ExploreDataObjects::IFMANWiffFilePtr ipFMANWiffFile;
ExploreDataObjects::IFMANWiffFile2Ptr ipFMANWiffFile2;
};
class ATL_NO_VTABLE CUserIDA :
public CComObjectRootEx<CComSingleThreadModel>,
public CComCoClass<CUserIDA, &CLSID_UserIDAObject>,
public IUserIDA
{
ExploreDataObjects::IFMANWiffFilePtr ipFMANWiffFile;
ExploreDataObjects::IFMANWiffFile2Ptr ipFMANWiffFile2;
class ATL\u NO\u VTABLE CUserIDA:
公共CComObjectRootEx,
公共课程,
公共IUserIDA
{
ExploreDataObjects::IFMANWiffFilePtr ipFMANWiffFile;
ExploreDataObjects::IFMANWiffFile2Ptr ipFMANWiffFile2;
我认为默认情况下,这些都是私有成员,和以前一样,所以我无法解释为什么这似乎是可行的。有人能解释一下吗?
< p>你的C++代码是正确的,除了下面的行:hr = ipFMANFile.CreateInstance(__uuidof(FMANFile));
它没有任何意义,因为ipFMANFile在下一个语句中再次初始化
不幸的是,此IDL声明:
IFMANWiffFile* GetWiffFileObject([in] BSTR WiffFileName, [in] long sample);
仅限于调试目的,因为它不支持通过HRESULT进行异常报告的本机COM机制。COM兼容声明为:
HRESULT GetWiffFileObject([in] BSTR WiffFileName, [in] long sample, [out, retval] IFMANWiffFile** fileInstance);
我相信您无法更改库的代码,因此我建议您尝试一些外部调试工具,如“procmon.exe”和“dbgview.exe”,以便在运行CPP测试用例时检查应用程序事件。查找所有失败的操作
我希望这会对您有所帮助谢谢您对这些工具的建议并对此进行了澄清。我现在就尝试使用它们。