经过一天的文字和隐喻的撞击,我恳求帮助:

我有一个非托管的C++项目,该项目被编译为DLL。我们称之为CPP项目。当前,它在不受管的环境中工作。另外,我创建了一个WPF项目,称为WPF项目。该项目是一个简单的项目,目前几乎为空。它包含一个窗口,我希望它使用Project 1中的代码。为此,我创建了一个CLR C++项目,该项目应称为Interop Project,也可以编译为DLL。

为简单起见,我将附上一些我已总结为基础的基本测试代码。

CPP项目具有以下两个测试文件:

tester.h

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

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

Interop项目具有以下文件:

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项目有一个使Interop项目不完整的窗口:

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

XAML本身有一个空窗口(默认创建)。

尝试运行WPF项目后,出现以下错误:



有趣的是,如果我不从CPP Project导出类,则不会收到此错误。说,如果我将tester.h更改为:
#pragma once
class NativeTester
{
public:
    void NativeTest()
    {
        int i = 0;
    }
};

但是,在这种情况下,我不能使用更复杂的类。如果像以前一样将实现转移到cpp文件,则由于未导出代码而导致无法解决的链接错误。我要实际使用的C++代码很大,有很多类,并且是面向对象的,因此我不能只将所有实现都移到h文件中。

请帮助我了解我一直试图解决但未成功的可怕错误。

谢谢。

最佳答案

这从一开始就出错,您的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。通过更改“常规+输出目录”设置来解决此问题,将其设置为$(SolutionDir)$bin\(ConfigurationName)

生成C++项目,并验证您可以在解决方案的bin\Debug目录中找到该DLL。并检查您是否也具有.lib文件,在构建C++/CLI项目时将需要该文件。作为额外的验证步骤,请从Visual Studio命令提示符处运行Dumpbin.exe/exports foo.dll,并检查您是否确实看到该类正在导出。

接下来,在C++/CLI项目中,您需要以相同的方式更改“输出目录”设置。将.lib文件添加到链接器的“其他依赖项”属性中。如果您跳过该步骤,将会得到您正在谈论的那种链接器错误。生成它并验证您再次在正确的bin\Debug目录中获得了DLL。

对“发布”配置重复这些更改。

设置项目依赖项后,WPF项目将依赖于C++/CLI项目。 C++/CLI项目取决于C++项目。这样可以确保以正确的顺序构建项目。

现在,您应该可以在WPF项目中使用这些DLL了。

关于c++ - C#与非托管C++互操作性的持续传奇,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/12509738/

10-12 22:16
查看更多