6

我阅读了一些文档,其中给出了与 C 兼容的函数的简单示例。

__declspec(dllexport) MyFunction();

我对此很满意。我写了一个小应用程序使用这个dll的功能。我使用了显式链接

LoadLibrary() 

功能。C 风格的函数可以正常工作。但是当我把我的课写成

namespace DllTest
{
class Test
{
public:
    __declspec(dllexport) Test();
    __declspec(dllexport) void Function( int );
    __declspec(dllexport) int getBar(void);
private:
    int bar;
};

}
#endif

它编译良好并创建了 Dll。在使用 C 风格的函数时,我只是从 LoadLibrary() 和 GetProcAddress(...) 函数中获取函数指针。

我以前的用法是

typedef void (*Function)(int);

int main()
{
   Function _Function;
   HINSTANCE hInstLibrary = LoadLibrary(TEXT("test.dll"));

   if (hInstLibrary)
   {
      _Function = (Function)GetProcAddress(hInstLibrary,"Function");
     if (_Function)
     {
        // use the function

但现在我不知道如何实例化我的类?如何使用显式链接或隐式链接?

任何有关代码示例的帮助将不胜感激。

4

2 回答 2

7

如果你试图实例化一个类,那么你需要在编译时知道它的结构。您可以通过创建一个抽象类来实现这一点,该类定义导入的类必须重新定义的实例方法。例如:

//interface.h

class TestInterface
{
public:
     virtual void Function( int ) = 0;
     virtual int getBar(void) = 0;
};

之后,在您的 DLL 中,您可以包含 interface.h,继承 TestInterface 并重新定义纯虚拟方法:

//test.h
namespace DllTest {
    class Test : public TestInterface
    {
    public:
         Test();
         void Function( int );
         int getBar(void);
    private:
        int bar;
    };
};

然后,您可以在 DLL 中定义一个分配 Test 对象的函数:

extern "C" __declspec(dllexport) TestInterface *allocate_test() {
    return new DllTest::Test();
}

最后,当您导入 DLL 时,查找符号“allocate_test”并使用它:

TestInterface *(*test_fun)() = (TestInterface *(*test_fun)())GetProcAddress(hInstLibrary,"allocate_test");
TestInterface *test_ptr = test_fun();
test_ptr->Function(12); //use you object
于 2012-02-15T16:13:10.407 回答
2

首先,请注意这是 Microsoft 的特殊性。不同的规则将适用于其他系统。

像以前那样写东西是行不通的,或者至少是痛苦的。您需要__declspec(dllexport)在定义函数的 DLL 中使用,但是__declspec(dllimport)在编译从另一个 DLL 调用函数的代码时。处理此问题的常用方法是使用指定 DLL 的特定宏名称,并执行以下操作:

#ifdef __WIN32
#ifdef MYMODULE_DLL
#define MYMODULE_EXPORT __declspec(dllexport)
#else
#define MYMODULE_EXPORT __declspec(dllimport)
#endif
#else
#define MYMODULE_EXPORT
#endif

将它放在包含在 DLL 中所有头文件中的头文件中,并MYMODULE_DLL在项目的命令行上定义。

此外,还可以导出整个类:

class MYMODULE_EXPORT DllTest
{
    //  ...
};

这具有导出或导入类的所有函数和静态成员的效果。

于 2012-02-15T15:37:46.113 回答