2012-02-13 13 views
0

なぜこれがInvalidProgramExceptionをスローしますか?私が見てきた別の変異体が言っている:ネイティブの戻り値の型がSystem.InvalidProgramExceptionをスローするのはなぜですか?

  1. JITは、内部の制限が発生しました。

  2. 共通言語ランタイムが無効なプログラムを検出しました。

私は、問題を再現するために私ができるような状況の最小セットに例を単純化してきました。あなたはこれを再現するために以下のコードをつかんでVS2010に貼り付けることができます。

以下の基本構造は、CppReferenceTestがネイティブ構造体を返すメソッドを含むCLR DLLアセンブリであることです。審判は、このメソッドを呼び出そうとしているCLRコンソールアプリケーションです。審判はCppReferenceTestへのプロジェクト参照を持っています。

他のテストから、CppReferenceTestの内部メソッドを呼び出すとInvalidProgramExceptionがスローされないことが分かります。また、戻り値を持たずに参照パラメータを取るようにメソッドのシグネチャを変更すると、例外がスローされないことも知っています。

アセンブリ1 - CppReferenceTest(CLRのDLLライブラリ)

ファイル: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; 
} 

アセンブリ2 - 審判(CLRコンソールアプリケーション)

ファイル:.NETで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; 
} 

答えて

3

、タイプIDはタイプがからロードされたアセンブリを含みます。したがって、参照設定の#includeは使用しないでください。#import(プロジェクト設定の[参照設定]タブは#importに相当します)のみを使用してください。

現在、#includeによってヘッダーファイルが作成されている場合、現在のアセンブリに_NativeStructタイプがあることを約束します。 main関数でこの型が使用されます。

実行時に、CLRはClass1::GetNativeEnum()CppReferenceTest.dllで定義された別の_NativeStructタイプを返すことを検出します。これらの型は互換性がなく、例外が発生します。

参照するアセンブリのメタデータで提供されている型を使用してください。


さらに、C++でtypedef struct _NativeStruct NativeStructを実行しないでください。それは必要ではなく、エラーメッセージを壊し、さらに悪いことに、予約済みの識別子と衝突します。

+0

お返事ありがとうございます。 '#include'を削除した場合、コンパイルエラー「エラーC2065: 'NativeStruct':宣言されていない識別子」が表示されます。どのようにしてそのネイティブ構造体への参照を取得できますか?私はSignedを 'Class1 :: GetNativeEnum([Out] NativeStruct&ns)'に変更した場合にも気付くでしょう。おそらく、2つのネイティブ型の等価なメモリレイアウトが原因でしょうか? – Bringer128

+0

'typedef'パートのコメントをありがとう。構造体は私が接続しているC構造体と一致していますので、実際の問題にできる限り近づけています。 – Bringer128

+0

@ Bringer128:これはやや奇妙です。クライアントで '#pragma make_public'を使用すると助けになりますか? –

関連する問題