从 DLL 动态导入 C++ 类

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/110833/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 12:55:03  来源:igfitidea点击:

Dynamically importing a C++ class from a DLL

c++windowsdllimport

提问by Shachar

What is the correct way to import a C++ class from a DLL? We're using Visual C++.

从 DLL 导入 C++ 类的正确方法是什么?我们正在使用 Visual C++。

There's the dllexport/exports.def+LoadLibrary+GetProcAddress trifecta, but it doesn't work on C++ classes, only C functions. Is this due to C++ name-mangling? How do I make this work?

有 dllexport/exports.def+LoadLibrary+GetProcAddress 三重奏,但它不适用于 C++ 类,仅适用于 C 函数。这是由于 C++ 名称修改吗?我如何使这项工作?

采纳答案by Shachar

Found the solution at http://www.codeproject.com/KB/DLL/XDllPt4.aspx

http://www.codeproject.com/KB/DLL/XDllPt4.aspx找到解决方案

Thanks for your efforts guys & girls

感谢你们的努力男孩和女孩

回答by Dror Helper

You need to add the following:

您需要添加以下内容:

extern "C"
{
...
}

to avoid function mangling.

以避免函数重整。

you might consider writing two simple C functions:

您可能会考虑编写两个简单的 C 函数:

SomeClass* CreateObjectInstace()
{
    return new SomeClass();
}

void ReleaseObject(SomeClass* someClass)
{
   delete someClass;
}

By only using those functions you can afterward add/change functionality of your object creation/deletion. This is sometimes called a Factory.

通过仅使用这些功能,您可以随后添加/更改对象创建/删除的功能。这有时被称为工厂。

回答by Graeme Perrow

Check out this question. Basically, there are two ways. You can mark the class using _dllexport and then link with the import library, and the DLL will be loaded automatically. Or if you want to load the DLL dynamically yourself, you can use the factory function idea that @titanae suggested

看看这个问题。基本上,有两种方法。您可以使用 _dllexport 标记该类,然后与导入库链接,DLL 将自动加载。或者如果你想自己动态加载DLL,你可以使用@titanae建议的工厂函数想法

回答by titanae

I normally declare an interface base class, use this declaration in my application, then use LoadLibrary, GetProcAddress to get the factory function. The factor always returns pointer of the interface type.

我通常声明一个接口基类,在我的应用程序中使用这个声明,然后使用 LoadLibrary、GetProcAddress 来获取工厂函数。该因子始终返回接口类型的指针。

Here is a practical example, exporting an MFC document/view from a DLL, dynamically loaded

这是一个实际示例,动态加载的 DLL 导出 MFC 文档/视图

回答by gbjbaanb

dllexport/dllimport works, place it before your class name in the header file and you're good to go.

dllexport/dllimport 工作,将它放在头文件中您的类名之前,您就可以开始了。

Typically you want to use dllexport in the dll, and dllimport in the exe (but you can just use dllexport everywhere and it works, doing it 'right' makes it tinily faster to load).

通常,您希望在 dll 中使用 dllexport,在 exe 中使用 dllimport(但您可以在任何地方使用 dllexport 并且它可以工作,“正确”使其加载速度更快)。

Obviously that is for link-time compilation. You can use /delayload linker directive to make it 'dynamic', but that's probably not what you want from the subject line.

显然,这是用于链接时编译。您可以使用 /delayload 链接器指令使其“动态”,但这可能不是您想要的主题行。

If you truly want a LoadLibrary style loading, you're going to have to wrap your C++ functions with "extern C" wrappers. The problem is because of name mangling, you could type in the fully-mangled name and it'd work.

如果你真的想要一个 LoadLibrary 风格的加载,你将不得不用“extern C”包装器来包装你的 C++ 函数。问题是由于名称修改,您可以输入完全修改的名称,它会起作用。

The workarounds are generally to provide a C function that returns a pointer to the correct class - COM works this way, as it exports 4 C functions from a dll that are used to get the interface methods inside the object in the dll.

解决方法通常是提供一个 C 函数,该函数返回指向正确类的指针 - COM 以这种方式工作,因为它从 dll 导出 4 个 C 函数,这些函数用于获取 dll 中对象内部的接口方法。