[英]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.