使用c ++ DLL中的函数

时间:2019-07-08 04:01:43

标签: c++ qt

我正在使用QT,并且使用DLL是QLibrary。但是我似乎无法在其中加载函数并在我的项目中使用它。

void Compose3wnThread::GenPrinterFile()
{
    lib_3wn = new QLibrary;
    lib_3wn->setFileName(qApp->applicationDirPath() + "/" + MyDLL);
    lib_3wn->load();

    if (lib->isLoaded())
    {
        typedef int (*initial)(char*, int, char*);
        initial function = (initial)lib_3wn->resolve("API_Initial");

        int result;
        result = 0;
        //result = (int)function("Nobel Superfine", 12, "D:\\final.3wn");

    }
}

lib_3wn是保存我的DLL的QLibrary对象。在运行上面的代码后,功能仍为0x0或没有任何值。这是我需要从DLL加载的功能。

int API_Initial(char *machineType, int totalLayers, char *fileName)
  

此函数来自定义我正在使用的DLL内部函数的文档。我不是自己创建DLL的。

我该如何解决?

3 个答案:

答案 0 :(得分:1)

来自QLibrary documentation

  

必须从库中将符号导出为C函数。这意味着,如果使用C ++编译器编译该库,则必须将该函数包装在extern "C"中。在Windows上,您还必须使用__declspec(dllexport)编译器指令

从DLL中显式导出函数。

您应在extern "C"的声明和定义中添加API_Initial

extern "C" int API_Initial(char *machineType, int totalLayers, char *fileName)

或将其包含在extern "C"块中:

extern "C" {
    int API_Initial(char *machineType, int totalLayers, char *fileName);
}

C ++具有函数重载功能,但是一个链接中的每个函数都需要一个唯一的名称才能使用。为此,名称是mangled以对其签名进行编码。这意味着int foo(int)int foo(double)具有不同的名称,并且链接程序可以区分它们,但是都没有命名为foo。一个被命名为?foo@@YAHH@Z,另一个被命名为?foo@@YAHN@Z(在Windows上。其他平台具有不同的名称处理方案,但是思想是相同的。)

这意味着当QLibrary查找名称API_Initial时找不到它。它可以 找到名称?API_Initial@@YAHPEADH0@Z,但是没有一个很好的独立于平台的方式来得出该名称。

在函数声明中添加extern "C"会禁用此名称修饰,但会阻止函数重载,将名称限制为全局名称空间,并将函数的接口限制为仅可复制的对象类型和指针。

答案 1 :(得分:0)

尝试

initial function = (initial)lib_3wn->resolve("_API_Initial");

initial function = (initial)lib_3wn->resolve("_API_Initial@4");

initial function = (initial)lib_3wn->resolve("@API_Initial@4");

取决于调用约定。有关更多信息,请参见this

答案 2 :(得分:0)

感谢您提供所有答案。我用@Antonio Dias的评论修复了它。我使用了Dependency Walker,然后看到我提到的DLL是依赖于(不希望使用的)两个[2]其他DLL文件。

先前的代码已经正确。