C# をスクリプト言語として C++ ライブラリに埋め込もうとしています。これは簡単な作業ではない可能性があることを認識していたので、最初にこれが可能かどうかを確認するために最小限のテスト プロジェクトを作成しました。
簡単なスクリプトを管理し、実行時にCSharpCodeProvider
. アセンブリは、C# コンソール アプリをテスト プロジェクトとして使用してテストされました (C# ソース ファイルがメモリ内でコンパイルされ、必要に応じて実行される場合)。
次のステップは、これを C++ アプリケーションで橋渡しすることでした。
私は何とかCOMを使用してそれを行うことができました。C# dll、クラス、およびインターフェイスを COM オブジェクトとしてエクスポートし、Regasm を使用して tlb ファイルを生成しました。
C++ プロジェクトでこれらのクラスのインスタンスを作成し、それらのメソッドを呼び出すことができWindows.Forms
、実際のロジックを実行する必要があるまで、すべて正常に動作しているように見えました (メッセージ ボックスの表示など)。ライブラリのホストとして C# コンソール アプリで既に動作しているため、スローしてはならない例外をスローするだけです。
COM コンポーネントをデバッグできるかどうかわからないので (この C# dll のコードに足を踏み入れることはできません)、大量のメッセージ ボックスと try-catch ブロックを追加しました。
コンパイルされたアセンブリから任意の型を取得しようとすると、壊れているようです。それはスローします:Reflection.ReflectionTypeLoadException
一方、コンパイルは失敗せず、エラー メッセージも生成されません。
C# を使用してこれらのメソッドをトリガーすると 100% 機能しますが、C++ から実行している間だけ何らかの理由で機能しなくなります。
これの原因は何ですか?または、私がやろうとしていることを別の方法で行うことができますか? このようなシナリオで COM を使用するのはどういうわけか正しいと思いますが、そのようなコードが壊れる原因となることに気付いていない側面がありますか?
編集: これは、COM としてエクスポートされたマネージ C# アセンブリです: http://nopaste.info/9da70dbcbd.html
したがって、これらのオブジェクトは次のように C++ アプリからアクセスされます: http://nopaste.info/50c4c9726a.html
また、スクリプトは、メッセージ ボックスを表示するメソッドから派生しIScript
て実装するクラスと同じくらい単純です。Execute
編集2:
スローされた例外に関する詳細は次のとおりです。
最後の文は、ファイルが見つからなかったことを意味します。
しかし、コンパイル時に次の行があるため、これは奇妙です。
これは「スクリプト」の内容です。
using System;
using System.Linq;
using System.Windows.Forms;
using System.Reflection;
using lame2.scripting;
namespace Olaboga
{
public class TestScript : IScript
{
public TestScript() { }
public void Execute(Event ev)
{
MessageBox.Show("Script that has been compiled from a source file has been invoked. TestScript.Execute");
}
}
}
編集3:
最後に、メモリ内でのコンパイルから一時ファイルへのコンパイルに切り替えた後、突然正常に動作し始めました。したがって、最後の質問は、メモリ内でコンパイルされているときに機能しなかった理由と、それが可能かどうかを誰かが知っている可能性があります。