5

文字通りにも比喩的にも壁に頭をぶつけて一日を過ごした後、私は助けを求めます:

DLLとしてコンパイルされたアンマネージC++プロジェクトがあります。それをCPPプロジェクトと呼びましょう。現在、管理されていない環境で動作します。さらに、WPFプロジェクトと呼ばれるWPFプロジェクトを作成しました。このプロジェクトは単純で、現在ほとんど空のプロジェクトです。単一のウィンドウが含まれており、プロジェクト1のコードを使用する必要があります。そのために、相互運用プロジェクトと呼ばれ、DLLとしてコンパイルされるCLRC ++プロジェクトを作成しました。

簡単にするために、私が要約したいくつかの基本的なテストコードを基本に添付します。

CPPプロジェクトには、次の2つのテストファイルがあります。

tester.h

#pragma once
extern "C" class __declspec(dllexport) NativeTester
{
public:
    void NativeTest();
};

tester.cpp

#include "tester.h"
    void NativeTester::NativeTest()
    {
        int i = 0;
    }

InteropProjectには次のファイルがあります。

InteropLib.h

#pragma once
#include <tester.h>
using namespace System;
namespace InteropLib {
    public ref class InteropProject
    {
    public:
        static void Test()
        {
            NativeTester nativeTester;
            nativeTester.NativeTest();
        }
    };
}

最後に、WPFプロジェクトには、相互運用プロジェクトを参照する単一のウィンドウがあります。

MainWindow.xaml.cs

using System;
using System.Windows;
using InteropLib;
namespace AppGUI
{
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            InteropProject.Test();
        }
    }
}

また、XAML自体には空のウィンドウがあります(デフォルトで作成されます)。

WPFプロジェクトを実行しようとすると、次のエラーが発生します。

System.Windows.Markup.XamlParseException:'指定されたバインディング制約に一致するタイプ'AppGUI.MainWindow'でのコンストラクターの呼び出しにより、例外がスローされました。行番号「3」および行位置「9」。---> System.IO.FileNotFoundException:ファイルまたはアセンブリ'InteropLib.dll'またはその依存関係の1つを読み込めませんでした。指定されたモジュールが見つかりませんでした。
AppGUI.MainWindow..ctor()で

興味深いことに、CPPプロジェクトからクラスをエクスポートしない場合、このエラーは発生しません。たとえば、次のように変更tester.hした場合:

#pragma once
class NativeTester
{
public:
    void NativeTest()
    {
        int i = 0;
    }
};

ただし、この場合、より複雑なクラスを使用することはできません。以前のように実装をcppファイルに移動すると、コードをエクスポートしないために未解決のリンケージエラーが発生します。実際に使用したいC++コードは大きく、多くのクラスがあり、オブジェクト指向であるため、すべての実装をhファイルに移動することはできません。

私が成功せずに解決しようとしてきたこの恐ろしいエラーを理解するのを手伝ってください。

ありがとう。

4

1 に答える 1

4

これは最初から間違っていました。tester.hファイルが正しくありません。テスタープロジェクトをビルドする場合、クラスには__declspec(dllexport)属性のみを含める必要があります。DLLを使用する他のプロジェクトは、__ declspec (dllimport)属性を持つクラスを参照する必要があります。tester.hのマクロを使用してこれを修正し始めます。

#undef EXPORTED
#ifdef BUILDING_DLL
#   define EXPORTED __declspec(dllexport)
#else
#   define EXPORTED __declspec(dllimport)
#endif

class EXPORTED NativeTester {
    // etc..
};

テスタープロジェクトでは、C / C ++、プリプロセッサー、プリプロセッサー定義を使用し、BUILDING_DLLを追加します。

次に、DLLが正しいディレクトリに保存されていることを確認します。これは例外が不平を言っていることです、それはDLLを見つけることができません。C ++プロジェクトのビルドディレクトリはDebugですが、WPFプロジェクトのビルドディレクトリはbin\Debugです。General + Output Directory設定を変更して修正し、それを作成し$(SolutionDir)$bin\(ConfigurationName)ます。

C ++プロジェクトをビルドし、ソリューションのbin\DebugディレクトリにDLLが戻っていることを確認します。また、.libファイルもあることを確認してください。C++/CLIプロジェクトをビルドするときに必要になります。追加の検証手順として、VisualStudioコマンドプロンプトからDumpbin.exe/ exports foo.dllを実行し、クラスが実際にエクスポートされていることを確認します。

次に、C ++ / CLIプロジェクトでは、同じ方法で出力ディレクトリの設定を変更する必要があります。.libファイルをリンカの追加の依存関係プロパティに追加します。そのステップをスキップすると、話していた種類のリンカーエラーが発生します。それをビルドし、DLLが正しいbin\Debugディレクトリに再度あることを確認します。

リリース構成に対してこれらの変更を繰り返します。

プロジェクトの依存関係を設定します。WPFプロジェクトはC++/CLIプロジェクトに依存します。C ++/CLIプロジェクトはC++プロジェクトに依存しています。これにより、プロジェクトが正しい順序で構築されていることが保証されます。

これで、WPFプロジェクトでこれらのDLLを使用することができます。

于 2012-09-20T13:37:23.257 に答える