简体   繁体   English

C ++ / CLI混合模式DLL创建

[英]C++/CLI Mixed Mode DLL Creation

I've got a native C++ DLL that I would like to have a C++/CLI wrapper layer for. 我有一个本机C ++ DLL,我希望有一个C ++ / CLI包装层。 From what I understood, if you simple added a C++/CLI class to the project, VS would compile as mixed mode, but I was apparently wrong as VS doesn't seem to be even touching the managed code. 根据我的理解,如果你简单地将C ++ / CLI类添加到项目中,VS将编译为混合模式,但我显然是错误的,因为VS似乎甚至没有触及托管代码。

So, given a pre-existing native code-base what exactly , step-by-step, do you need to do to create a mixed mode DLL, so that I can can link into that code from any .NET language? 所以,对于一个已经存在的本地代码库究竟是什么,一步一步的,你需要做的,创建一个混合模式DLL,这样我可以从任何.NET语言链接到该代码?

*I need to do this because my native code uses C++ classes that I cannot P/Invoke into. *我需要这样做,因为我的本机代码使用我不能P / Invoke进入的C ++类。

Well, no, it doesn't get to be mix-mode until you tell the C++/CLI compiler that your legacy DLL was written in unmanaged code. 好吧,不,它告诉C ++ / CLI编译器你的遗留DLL是用非托管代码编写的,它不会成为混合模式。 Which should have been noticeable, you should have gotten linker errors from the unmanaged DLL exports. 哪个应该引人注意,你应该从非托管DLL导出中获得链接器错误。 You need to use #pragma managed: 您需要使用#pragma managed:

#pragma managed(push, off)
#include "oldskool.h"
#pragma comment(lib, "oldskool.lib")
#pragma managed(pop)

using namespace System;

public ref class Wrapper {
private:
    COldSkool* pUnmanaged;
public:
    Wrapper() { pUnmanaged = new COldSkool; }
    ~Wrapper() { delete pUnmanaged; pUnmanaged = 0; }
    !Wrapper() { delete pUnmanaged; }
    void sampleMethod() { 
        if (!pUnmanaged) throw gcnew ObjectDisposedException("Wrapper");
        pUnmanaged->sampleMethod(); 
    }
};

防止/ clr影响现有代码的一个好方法是将所有现有代码编译到本机静态库中,然后在C ++ / CLI dll的链接步骤中包含该静态库。

开始一个新的C ++ / CLI项目,然后将您的本机类移动到它。

Instead of Turning on the "Common Language RunTime Support" at the Project Level, it's possible to enable it on a file-by-file basis only by looking at the Properties of the File, and going to C/C++ | 而不是在项目级别打开“公共语言运行时支持”,只能通过查看文件的属性,然后转到C / C ++,逐个文件地启用它。 General | 一般| Common Language Support. 共同语言支持。

This might make it easier to have your native and C++/CLI code in the same project, rather than creating a separate C++/CLI DLL just containing the wrapper, or having to use lots of managed/unmanaged pragmas. 这可能使您更容易在同一个项目中使用本机和C ++ / CLI代码,而不是创建仅包含包装器的单独C ++ / CLI DLL,或者必须使用大量托管/非托管编译指示。

So just do that on the C++/CLI .NET wrapper class you want to write. 所以,只需在要编写的C ++ / CLI .NET包装器类上执行此操作。

If you has a source code of the DLL with native C++, you can use managed C++ in the mixed mode. 如果您具有本机C ++的DLL源代码,则可以在混合模式下使用托管C ++。 Microsoft has for some time a reference project of migration of some well known DirectX game to .NET. 微软已经有一段时间将一些着名的DirectX游戏迁移到.NET的参考项目。 One used managed C++ in the mixed mode. 一个在混合模式下使用托管C ++。 A part of code was rewritten as managed code. 部分代码被重写为托管代码。 A part was shortly changed to be compiled as C++ in the mixed mode and a part was compiled as assembly code (because of performance reason), but used also directly inside of managed code as unsafe code. 一部分很快被改为在混合模式下编译为C ++,一部分被编译为汇编代码(由于性能原因),但也直接在托管代码内部用作不安全的代码。 Such kind of migration follow as a result to really very good performance in the end application. 因此,这种迁移会在最终应用程序中实现非常好的性能。 In this way you don't spend time for marshaling between native and managed code. 这样,您就不会花时间在本机代码和托管代码之间进行编组。 Marshaling between safe and unsafe managed code is much quickly. 安全和不安全的托管代码之间的编组很快。 Probably you should also choose this way? 也许你也应该选择这种方式?

Another way calling native code from DLL inside of manged .NET code is well known. 在manged .NET代码中从DLL调用本机代码的另一种方法是众所周知的。 Every C++ function has undecorated names (use http://www.dependencywalker.com/ to see there). 每个C ++函数都有未修饰的名称(使用http://www.dependencywalker.com/查看)。 If your C++ DLL export classes and not C-like functions, this DLL is bad designed. 如果您的C ++ DLL导出类而不是类C函数,则此DLL设计不当。 Good designed DLL either exports C-like functions or export COM-interfaces. 设计良好的DLL既可以导出类似C的函数,也可以导出COM接口。 If you have such "bad" DLL and don't want spend time to write a COM, you can easy write one more DLL which will be play a stub role. 如果你有这样的“坏”DLL并且不想花时间编写COM,你可以轻松编写一个将扮演存根角色的DLL。 This DLL imports all C++ classes (see http://msdn.microsoft.com/en-us/library/81h27t8c.aspx , Exporting a C++ class from a DLL and http://www.codeproject.com/KB/cpp/howto_export_cpp_classes.aspx for example) from "bad" DLL and export C-like function. 此DLL导入所有C ++类(请参阅http://msdn.microsoft.com/en-us/library/81h27t8c.aspx从DLL导出C ++类http://www.codeproject.com/KB/cpp/例如, howto_export_cpp_classes.aspx来自“坏”DLL并导出类似C的函数。 This way is also OK. 这种方式也行。

The C++ project file needs the /clr option. C ++项目文件需要/ clr选项。 This can be set for the whole project on the general tab, I believe, or set on individual files. 我相信,这可以在常规选项卡上为整个项目设置,也可以在单个文件上设置。

Once the clr option is specified Visual Studio will build that class using C++/CLI. 一旦指定了clr选项,Visual Studio将使用C ++ / CLI构建该类。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM