Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/126.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# COM接口修改突然开始导致异常 几年前,我继承了一个C应用程序,它使用了非托管C++ DLL中定义的COM对象。从那以后,我一直在成功地调整对象接口,但在VS2012升级之后(可能不相关),函数签名的添加和更改突然受到随机异常的惩罚,如ExecutionEngineeException和SehexException_C#_C++_Com_Visual Studio 2012 - Fatal编程技术网

C# COM接口修改突然开始导致异常 几年前,我继承了一个C应用程序,它使用了非托管C++ DLL中定义的COM对象。从那以后,我一直在成功地调整对象接口,但在VS2012升级之后(可能不相关),函数签名的添加和更改突然受到随机异常的惩罚,如ExecutionEngineeException和SehexException

C# COM接口修改突然开始导致异常 几年前,我继承了一个C应用程序,它使用了非托管C++ DLL中定义的COM对象。从那以后,我一直在成功地调整对象接口,但在VS2012升级之后(可能不相关),函数签名的添加和更改突然受到随机异常的惩罚,如ExecutionEngineeException和SehexException,c#,c++,com,visual-studio-2012,C#,C++,Com,Visual Studio 2012,我的理解是,该应用程序使用免费注册的COM。没有DLLRegisterServer实现,我在注册表中也没有提到接口GUID,只有C#中的一个 和C++头中的一个。< /P> interface __declspec(uuid("C2427CB1-D6AE-49e8-B266-114F981C3353")) IDC : IUnknown { 但可以肯定的是,我决定将一个新的guid交换到这两个位置,并发现它阻止了C#识别该类: System.InvalidCastException Unabl

我的理解是,该应用程序使用免费注册的COM。没有DLLRegisterServer实现,我在注册表中也没有提到接口GUID,只有C#中的一个

和C++头中的一个。< /P>

interface __declspec(uuid("C2427CB1-D6AE-49e8-B266-114F981C3353"))
IDC : IUnknown
{
但可以肯定的是,我决定将一个新的guid交换到这两个位置,并发现它阻止了C#识别该类:

System.InvalidCastException

Unable to cast COM object of type 'System.__ComObject' to interface type 'Apx.IDC'.
This operation failed because the QueryInterface call on the COM component for the
interface with IID '{the new guid}' failed due to the following error:
No such interface supported (Exception from HRESULT: 0x80004002 (E_NOINTERFACE)).
(显然,上面的错误通常是由混合应用程序状态引起的,但交换guid不会导致这种情况)。因此,我推断一定有其他相关细节与我的更改相冲突。但那可能在哪里呢?谢谢你的阅读

编辑:

一个例外的例子是

First-chance exception at 0x000007feec748be4 (clr.dll) in Apex.exe: 0xC0000005:
Access violation reading location 0xffffffffffffffff.
The Common Language Runtime cannot stop at this exception. Common causes include:
incorrect COM interop marshalling, and memory corruption. To investigate further,
using native-only debugging.

An unhandled exception of type 'System.ExecutionEngineException' occurred in Apex.exe
为了

以堆栈跟踪结束

[Native to Managed Transition]  
Apex.Graphics64.dll!CDisplayList::LoadRenderRecs(void * f=0x000000000000056c, CDisplayList * pComparison=0x0000000023ad2cf0)  Line 1772 C++
Apex.Graphics64.dll!CDisplayList::Load(void * f=0x000000000000056c, unsigned short version=0x0002, CDisplayList * pComparison=0x0000000023ad2cf0)  Line 1845 + 0x26 bytes   C++
Apex.Graphics64.dll!CBaseDC::LoadDisplayList(void * f=0x000000000000056c, CDisplayList * pList=0x0000000023ad2cf0, unsigned short version=0x0002, CDisplayList * pComparison=0x0000000023ad2cf0)  Line 1896 + 0x33 bytes    C++
[Managed to Native Transition]  
Apex.exe!Apex.DDC.LoadDisplayList(System.IO.FileStream file = {System.IO.FileStream}, Apex.DisplayList displayList = {Apex.DisplayList}, ushort version = 0x0002, Apex.DisplayList comparison = null) Line 1124 + 0xaf bytes    C#
Apex.exe!Apex.DisplayList.Load(System.IO.FileStream f = {System.IO.FileStream}, ushort loadVersion = 0x0002, Apex.INode stubsRoot = {Apex.ViewPort3D}, Apex.DisplayList comparison = null) Line 166 + 0x53 bytes    C#

确切的崩溃点有所不同——在这里,它实际上设法进入了LoadDisplayList(),这比平常要好。由于崩溃意味着堆损坏,我尝试将函数的签名剥离为无参数的void return,将其内容缩减为跟踪,并在对象创建后立即调用它——仍然是为了获得崩溃。如果我将同一个函数移到定义的顶部,它不会崩溃,在这种情况下,其他一些接口函数会崩溃,这使我认为这更可能是一个COM问题,而不是算法级内存损坏。

我想我已经解决了这个问题。一旦我能够进入DLL,一个弹出窗口告诉我源代码与可执行文件不匹配,这让我调查了另一个长期存在但以前没有问题的怪癖,即DLL的链接器/General/Output文件不在项目的General/Output目录中(警告MSB8012)。清除此异常后,我能够成功更改guid,因此VS2012使用这些设置的方式似乎与旧版本略有不同。道德…不要让警告挂起。

澄清一下:您一直在更改函数的签名,当双方都更新和重建时,会发生异常。异常和调用堆栈的确切信息是什么?@ZdeslavVojkovic,对不起,这条评论是自己提交的!我已经在描述中添加了这些细节。在我看来,这似乎是不同组件中的接口布局不匹配。我假设在重新排序方法时修改了两个DLL。互操作dll呢?如果你不更新它,封送就会失败。@ZdeslavVojkovic:是的,我甚至构建了一个简单的解析器来仔细检查顺序。除了C++的exe和c++的dll之外,唯一的其他DLL是EXE内部控件的ActiveX包装器。只是好奇,为什么你要重复C语言中的接口定义?那是个坏习惯。您只需使用TlbImp.exe实用程序导入类型库,它将自动创建具有正确接口定义的程序集。
[PreserveSig] [return: MarshalAs(UnmanagedType.I1)]
bool LoadDisplayList(IntPtr fileHandle, IntPtr pDisplayList,
UInt16 version, IntPtr pComparison);
virtual bool __stdcall LoadDisplayList(HANDLE fileHandle, class CDisplayList * pDisplayList,
WORD version, CDisplayList * pComparison) = 0;
[Native to Managed Transition]  
Apex.Graphics64.dll!CDisplayList::LoadRenderRecs(void * f=0x000000000000056c, CDisplayList * pComparison=0x0000000023ad2cf0)  Line 1772 C++
Apex.Graphics64.dll!CDisplayList::Load(void * f=0x000000000000056c, unsigned short version=0x0002, CDisplayList * pComparison=0x0000000023ad2cf0)  Line 1845 + 0x26 bytes   C++
Apex.Graphics64.dll!CBaseDC::LoadDisplayList(void * f=0x000000000000056c, CDisplayList * pList=0x0000000023ad2cf0, unsigned short version=0x0002, CDisplayList * pComparison=0x0000000023ad2cf0)  Line 1896 + 0x33 bytes    C++
[Managed to Native Transition]  
Apex.exe!Apex.DDC.LoadDisplayList(System.IO.FileStream file = {System.IO.FileStream}, Apex.DisplayList displayList = {Apex.DisplayList}, ushort version = 0x0002, Apex.DisplayList comparison = null) Line 1124 + 0xaf bytes    C#
Apex.exe!Apex.DisplayList.Load(System.IO.FileStream f = {System.IO.FileStream}, ushort loadVersion = 0x0002, Apex.INode stubsRoot = {Apex.ViewPort3D}, Apex.DisplayList comparison = null) Line 166 + 0x53 bytes    C#