11

我一直在尝试在 Visual Studio 2010 pro/C# 项目中使用 Robert Giesecke 的扩展“非托管导出”。然而,我无法让它工作 - 当我检查编译的 DLL 以进行导出时,查看器(http://www.nirsoft.net/utils/dll_export_viewer.html)总是空的,似乎没有定义导出全部。

我几乎复制了示例并将构建/配置管理器/活动平台设置为 x86。我可以以某种方式检查执行所有魔术的 MSBuild 任务是否实际运行?项目文件应该包含什么(对我来说它似乎是空的?)

4

2 回答 2

25

我建议您以记录的方式执行此操作,而不是依赖不提供支持的作者的无证破解。让我们用一个例子来做:

namespace Publics {
    public class Class1 {
        public static void Run() { 
            // Stuff...
        }
    }
}

将新的 C++/CLI 类库添加到您的项目中。右键单击解决方案,添加,新建项目。打开“其他语言”节点、Visual C++、CLR,然后选择“类库”项目模板。右键单击新项目,Properties,Common Properties,Framework and References,单击Add New Reference按钮。从“项目”选项卡中,选择要导出其方法的 C# 项目。

用 //TODO 注释删除预先生成的空类并编写这样的代码:

extern "C" __declspec(dllexport)
void __stdcall Example() 
{
    Publics::Class1::Run();
}

构建您的解决方案。通过在 DLL 上运行 dumpbin.exe /exports 检查示例函数是否已导出。您应该会看到与此类似的内容:

      1    0 00001020 _Example@0 = _Example@0

除了名称和调用约定之外,您现在还有很多选择来调整导出的函数。如果要导出实例方法而不是静态方法,可以编写如下函数,例如:

extern "C" __declspec(dllexport)
void __stdcall Example() 
{
    Publics::Class1^ obj = gcnew Publics::Class1;
    obj->Run();
}

等等,如果您要详细说明,则需要对 C++/CLI 语言有一定的了解。最后但并非最不重要的一点是,您也可能会发现在您最初尝试使 Giesecke 的 IL 重写器工作时出了什么问题。否则,它使用与 C++/CLI 编译器用于导出托管方法的完全相同的技术。

于 2013-06-16T09:23:16.640 回答
1

我一直在使用 1.1.3 版,发现现在有一个支持 NuGet 的更新版本。我只是做了一个测试。

我可以以某种方式检查执行所有魔术的 MSBuild 任务是否实际运行?

您可以使用命令行从 MSBuild 获取更多详细信息,或调整 Visual Studio 请求的详细程度:Tools > Options > Project and Solutions > Build and Run > MSBuild project build output verbosity[VS 2010]。完成故障排除后,您可能希望立即重置它。

我看到目标和任务正在被调用,但直到我将项目平台切换到 x86 才看到任何结果。然后我看到各种相关的日志条目,包括Adding .vtentry:0 .export....

项目文件应该包含什么(对我来说它似乎是空的?)

项目文件中不需要太多。NuGet 完成所有工作:对 DllExport 程序集的引用和目标文件的包含。

我能想到的几件事可能会让你绊倒:

  1. 确保您实际上是在构建项目。解决方案构建管理器可以有一些项目未设置为为选定的解决方案配置构建。
  2. 确保您正在检查正确的 DLL。构建任务将路径写入构建日志。该行以Assembling.
于 2013-06-16T01:14:58.293 回答