C#“非托管出口”

时间:2013-06-15 20:58:17

标签: c# unmanaged

我一直在尝试使用Robert Giesecke在Visual Studio 2010 pro / C#项目中使用的扩展名“Unmanaged Exports”。然而,我无法使它工作 - 当我检查编译的DLL导出时,查看器(http://www.nirsoft.net/utils/dll_export_viewer.html)总是空出来,根本没有定义导出。

我已经复制了示例,并将build / config manager / active平台设置为x86。我可以以某种方式检查执行所有魔法的MSBuild任务是否实际运行?项目文件应该包含什么(对我来说似乎是空洞的?)

2 个答案:

答案 0 :(得分:21)

我建议你以记录的方式执行此操作,而不是依赖于未提供支持的作者的无证件黑客攻击。让我们用一个例子来做:

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

将新的C ++ / CLI类库添加到项目中。右键单击解决方案,添加,新建项目。打开“其他语言”节点,Visual C ++,CLR,然后选择“类库”项目模板。右键单击新项目,“属性”,“公共属性”,“框架和引用”,然后单击“添加新引用”按钮。从“项目”选项卡中,选择要导出其方法的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();
}

Etcetera,如果您要详细说明,则需要熟悉C ++ / CLI语言。最后但同样重要的是,您也可能会发现您最初尝试使Giesecke的IL重写器工作出现问题。否则,它使用与C ++ / CLI编译器用于导出托管方法完全相同的技术。

答案 1 :(得分: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开头。