私が知る限り、パディングに互換性がある場合、ライブラリ間で構造体を渡すことは安全です。そのため、単一のメンバーを含む構造体を使用してテストを作成しましたが、返された構造体を読み取るときにまだランタイム エラーが発生します。
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;
}
VS2012 の実行可能ファイルである mingw でプラグインをコンパイルしました。また、const char* を int に置き換えようとしました。この場合、ランダムな整数が得られます。単一の要素を持つ構造体を渡すのはあまり意味がないことはわかっていますが、それでも何が問題なのか疑問に思っています。