为什么会抛出InvalidProgramException?我见过的不同变种说:
JIT遇到内部限制。
- 醇>
Common Language Runtime检测到无效程序。
我已经将示例简化为可以重现该问题的最小环境。您应该能够获取以下代码并将其粘贴到VS2010中以重现这一点。
下面的基本结构是CppReferenceTest是一个CLR DLL程序集,它包含一个返回本机结构的方法。 Referee是一个试图调用此方法的CLR控制台应用程序。裁判有一个项目参考CppReferenceTest。
我从其他测试中得知,调用CppReferenceTest内部的方法不会抛出InvalidProgramException。我也知道如果我更改方法签名以获取引用参数而不是返回值,则不会抛出任何异常。
文件:NativeHeader.h
#pragma managed(push, off)
typedef struct _NativeStruct {
int val1;
int val2;
} NativeStruct;
#pragma managed(pop)
文件:CppReferenceTest.h
#pragma once
#include "NativeHeader.h"
using namespace System;
#pragma make_public(_NativeStruct)
namespace CppReferenceTest {
public ref class Class1
{
public:
static NativeStruct GetNativeEnum();
};
}
文件:CppReferenceTest.cpp
#include "stdafx.h"
#include "CppReferenceTest.h"
using namespace CppReferenceTest;
NativeStruct Class1::GetNativeEnum()
{
NativeStruct ns = {1, 2};
return ns;
}
文件:Referee.cpp
#include "stdafx.h"
#include "NativeHeader.h"
using namespace System;
using namespace CppReferenceTest;
int main(array<System::String ^> ^args)
{
NativeStruct ns = Class1::GetNativeEnum();
Console::WriteLine(L"Hello World");
return 0;
}
答案 0 :(得分:3)
在.NET中,类型标识包括从中加载类型的程序集。因此,您不应将#include
与托管引用一起使用,仅#import
(“项目设置”中的“引用”选项卡等同于#import
)。
现在发生的事情是,通过#include
- 头文件,您保证当前程序集中有_NativeStruct
类型。您的main
函数使用此类型。
然后,在运行时,CLR发现Class1::GetNativeEnum()
返回_NativeStruct
中定义的其他CppReferenceTest.dll
类型。这些类型不兼容,您将获得例外。
只需使用您引用的程序集的元数据中提供的类型。
除此之外,不要在C ++中使用typedef struct _NativeStruct NativeStruct
。没有必要,它会搞错误消息,更糟糕的是,它与保留的标识符冲突。