1

私はDllと共にプロジェクトを構築しています。

Dll はネイティブ コードをサポートする必要があるため、/clr として宣言しました。私のプロジェクトは最初は /clr プロジェクトでもあり、すべて問題ありませんでした。ただし、いくつかの NUnit テストを含めたいので、メイン プロジェクトを /clr から /clr:pure に切り替える必要がありました。

すべては引き続きコンパイルされますが、Dll 呼び出しで実行時エラーが発生します。/clr に戻ると、すべて問題ありません

私のDLLでは、エクスポートされた関数は次のように宣言されています:

#define DllExport   __declspec( dllexport )
DllExport bool DisplayScan(bool bShow, bool bAllPasses) { }

エクスポートされたすべての関数の実際の名前を含む .def ファイルも作成しました

LIBRARY "Controller"
EXPORTS
DisplayScan

私のメインプロジェクトから、私のインポートは次のように宣言されています:

#define _DllImport [DllImport("Controller.dll", CallingConvention = CallingConvention::Cdecl)] static
_DllImport bool DisplayScan(bool bShow, bool bAllPasses)

誰もそのような問題に遭遇したことがありますか?

4

4 に答える 4

3

OK、すべてが機能しています

実際、それは最初から機能しています。

道徳的: char* を std::string にキャストしようとしないでください

奇妙なことに、関数から戻るまでは /clr で問題ありません。/clr:pure ですぐにクラッシュする

于 2008-11-14T22:31:57.520 に答える
3

基本的に、サポートされていないことを行っています。/clr:純粋なネイティブ DLL エクスポート。この MSDN の記事から引用されているように、「純粋なアセンブリのエントリ ポイントは __clrcall 呼び出し規約を使用するため、純粋なアセンブリはネイティブ関数から呼び出し可能な関数をエクスポートできません。」

最善の回避策がわかりません。ただし、少し試してみると、/clr オプションを使用して __clrcall 呼び出し規約を利用できる可能性があります。 役に立つかもしれないリンクを次に示します。私が収集できることから、これらのマネージド クラスをエクスポートし、マネージド NUnit テスト プロジェクトなどのマネージド アセンブリ内からそれらを使用できるはずですが、アンマネージド エクスポートは別のメソッド シグネチャで保持する必要があります。エクスポートを介して .net クラスを公開するとすぐに、__clrcall 呼び出し規約を使用する必要があることに注意してください。

于 2008-11-14T22:36:50.070 に答える
1

/clr:pure の利点

パフォーマンスの向上: 純粋なアセンブリには MSIL のみが含まれているため、ネイティブ関数はなく、マネージ/アンマネージ遷移は必要ありません。(P/Invoke による関数呼び出しは、この規則の例外です。)

AppDomain の認識: マネージ関数と CLR データ型はアプリケーション ドメイン内に存在し、それらの可視性とアクセシビリティに影響します。純粋なアセンブリはドメインに対応しているため (型ごとに __declspec(appdomain) が暗示されます)、他の .NET コンポーネントからその型や機能にアクセスするのがより簡単かつ安全になります。その結果、純粋なアセンブリは、混合アセンブリよりも他の .NET コンポーネントと簡単に相互運用できます。

非ディスク読み込み: 純粋なアセンブリをメモリ内に読み込み、ストリーミングすることもできます。これは、.NET アセンブリをストアド プロシージャとして使用する場合に不可欠です。これは、Windows の読み込みメカニズムに依存するため、実行するためにディスク上に存在する必要がある混合アセンブリとは異なります。

リフレクション: 混合実行可能ファイルをリフレクションすることはできませんが、純粋なアセンブリは完全なリフレクション サポートを提供します。詳細については、リフレクション (C++/CLI) を参照してください。

ホストの制御性: 純粋なアセンブリには MSIL のみが含まれているため、CLR をホストし、その既定の動作を変更するアプリケーションで使用すると、混合アセンブリよりも予測可能かつ柔軟に動作します。

/clr:pure の制限事項

このセクションでは、/clr:pure で現在サポートされていない機能について説明します。

純粋なアセンブリは、アンマネージ関数から呼び出すことはできません。したがって、純粋なアセンブリは、COM インターフェイスを実装したり、ネイティブ コールバックを公開したりすることはできません。純粋なアセンブリは、__declspec(dllexport) または .DEF ファイルを介して関数をエクスポートできません。また、__clrcall 規則で宣言された関数は、__declspec(dllimport) を介してインポートできません。ネイティブ モジュール内の関数は純粋なアセンブリから呼び出すことができますが、純粋なアセンブリはネイティブ呼び出し可能な関数を公開できないため、純粋なアセンブリ内の機能を公開するには、混合アセンブリ内のマネージド関数を使用して行う必要があります。詳細については、「方法: /clr:pure (C++/CLI) に移行する」を参照してください。

ATL および MFC ライブラリは、Visual C++ のピュア モード コンパイルではサポートされていません。

純粋な .netmodules は、Visual C++ リンカへの入力として受け入れられません。ただし、純粋な .obj ファイルはリンカーによって受け入れられ、.obj ファイルには netmodules に含まれる情報のスーパーセットが含まれます。詳細については、リンカー入力としての .netmodule ファイルを参照してください。

コンパイラ COM サポート (#import) はサポートされていません。純粋なアセンブリにアンマネージ命令が導入されるためです。

アラインメントと例外処理の浮動小数点オプションは、純粋なアセンブリでは調整できません。そのため、__declspec(align) は使用できません。これにより、fpieee.h などの一部のヘッダー ファイルが /clr:pure と互換性がなくなります。

PSDK の GetLastError 関数は、/clr:pure を使用してコンパイルすると、未定義の動作を引き起こす可能性があります。

于 2012-05-04T06:05:26.907 に答える
0

あなたの問題はconventionCallingConvention = CallingConvention::Cdecl ...を呼び出すことです...そのように関数を定義するか、stdcallまたはclrcallを使用してください。cleclは純粋なC用です

または問題はここにあります: 関数 extern が静的ではないことを定義します

于 2009-09-09T15:34:03.980 に答える