【问题标题】:Is it possible to write a C++ .dll library to export methods which is written within namespace and class?是否可以编写一个 C++ .dll 库来导出在命名空间和类中编写的方法?
【发布时间】:2016-12-02 11:35:52
【问题描述】:

我是 C++ dll 概念的新手,只是想知道,是否可以编写一个 C++ .dll 库来导出写在命名空间和类中的方法?

我尝试过的...

/*JNLib.h Header File*/
#ifndef __JNLIB_H__
#define __JNLIB_H__
#include <string>
#include <vector>
using namespace std;

    namespace JNLib
    {
        class __declspec(dllexport) JNLibClass
        {
        public:
                void split_string();
        };
    }

#endif

在 .cpp 文件中

/*JNLib.cpp File*/
#include "stdafx.h"
#include "JNLib.h"

    namespace JNLib
    {
        void JNLibClass::split_string()
        {
            cout<<"Library called"<<std::endl;
        }
    }

现在我可以编译这个项目并成功获取.dll 文件。在另一个项目中,我可以使用LoadLibrary() 方法成功加载库(.dll)文件,但GetProcAddress 方法每次都返回null。我写的代码是

typedef void (CALLBACK  *f_funci)();
HINSTANCE dllinstance = LoadLibrary(L"..\\myLIB\\JNLib.dll");
f_funci funci = (f_funci)GetProcAddress(dllinstance, "split_string");

请让我知道我做错了什么。

【问题讨论】:

  • 查找符号修改。您还可以使用 Windows 上的 dumpbin 工具(Visual Studio 附带)来检查实际导出的符号名称。
  • 除了name-mangling 问题之外,您在加载该函数时还有另一个问题。问题是您尝试加载非静态成员函数,因为它是非成员函数。非静态成员函数需要一个 object 才能被调用。
  • 你为什么不包含头文件(用dllimport而不是dllexport)并链接到dll?
  • 这是微软的一个很好的演练:msdn.microsoft.com/en-us/library/ms235636.aspx
  • 正如一些程序员老兄所说,split_string 是一个非静态成员函数。请记住,与 C# 等语言不同,C++ 允许使用非成员函数。换句话说,如果JNLibClass 纯粹是作为放置一些实用功能的地方而存在的,你可以摆脱它。

标签: c++ visual-studio-2010 dll


【解决方案1】:

库中没有名为 split_string 的符号 - 名称一直是 mangled

您可以使用 DLL 上的dumpbin 工具来查看导出了哪些符号。或者,您可以将要导出的名称空间/类移出到 extern "C" 块中(这会停止名称修改)。

【讨论】:

    【解决方案2】:

    可以从 DLL 导出其命名空间内的方法。

    首先,用你的命名空间定义你的方法,就像上面@OMGtechy 写的那样——添加extern "C" 装饰:

    namespace MyNameSpace{
        extern "C" void foo();
    }
    

    其次,编辑您的项目def 文件以指定您的命名空间映射:

    LIBRARY MyDllName
    EXPORTS
        MyNameSpace::foo=foo
    

    现在,在加载方法时指定命名空间:

    typedef void(*PFN_MYFUNC)();
    
    HINSTANCE  hLib = ::LoadLibrary("MyDllName");
    PFN_MYFUNC pfn  = (PFN_MYFUNC)::GetProcAddress( hLib, "MyNameSpace::foo");
    

    【讨论】:

      猜你喜欢
      • 2011-02-27
      • 1970-01-01
      • 1970-01-01
      • 2010-09-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多