繁体   English   中英

通过使用不同编译器构建的显式加载的dll通过值传递结构

[英]Passing struct by value from an explicitly loaded dll built with a different compiler

据我所知,如果填充兼容,则跨库传递结构是安全的。 因此,我使用包含单个成员的结构编写了一个测试,但是在读取返回的结构时仍然遇到运行时错误。

PluginInterface.h:

#ifndef PLUGIN_INTERFACE_H
#define PLUGIN_INTERFACE_H

typedef struct {
    const char *name;
} DataStruct;

class PluginInterface {
public:
    virtual DataStruct __cdecl getData() = 0;
};

#endif // PLUGIN_INTERFACE_H

Plugin.h:

#ifndef PLUGIN_H
#define PLUGIN_H

#include "PluginInterface.h"

class Plugin : public PluginInterface {
public:
    DataStruct __cdecl getData();
};

#endif // PLUGIN_H

Plugin.cpp:

#include "Plugin.h"

DataStruct Plugin::getData() {
    DataStruct data;
    data.name = "name of plugin";
    return data;
}

extern "C" __declspec(dllexport) PluginInterface* getInstance() {
    return new Plugin;
}

main.cpp中:

#include <iostream>
#include "windows.h"
#include "PluginInterface.h"

typedef PluginInterface* (*PluginCreator) ();

int main()
{
    HINSTANCE handle = LoadLibrary("Plugin.dll");
    if (handle == nullptr) {
        std::cout << "Unable to open file!" << std::endl; return 0;
    }

    PluginCreator creator = (PluginCreator)GetProcAddress(handle, "getInstance");
    if (creator == nullptr) {
        std::cout << "Unable to load file!" << std::endl; return 0;
    }

    PluginInterface* plugin = creator();
    if (plugin == nullptr) {
        std::cout << "Unable to create plugin!" << std::endl; return 0;
    }

    DataStruct data = plugin->getData();
    std::cout << "so far so good" << std::endl;

    std::cout << data.name << std::endl; // Access violation

    return 0;
}

我用mingw编译了插件,使用VS2012进行了编译。 我还尝试将const char *替换为int,在这种情况下,我得到了一个随机整数。 我知道传递带有单个元素的结构没有多大意义,但我仍然想知道问题出在哪里。

问题不在于通过值传递结构,因为如果返回结构的函数是声明为extern "C"的非成员函数,这将起作用。 问题在于对虚拟函数getData()的调用。 在您的示例中,VS2012编译器生成代码以通过指向对象的指针来调用虚拟函数,但该对象是由其他编译器生成的代码创建的。 失败是因为两个编译器之间的C ++ ABI不同-这意味着虚拟功能的基础实现是不同的。

creator的调用成功,因为两个编译器具有相同的C ABI基础实现。 如果要跨库边界使用C ++,则需要确保使用相同的C ++ ABI版本编译这些库。 请注意,同一编译器的不同版本之间可能会有所不同。

暂无
暂无

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

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