经过一天的文字和隐喻的撞击,我恳求帮助:
我有一个非托管的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/