Есть ли способ сделать библиотеки С++, созданные с помощью разных компиляторов, совместимыми друг с другом? Классы могут иметь фабричные методы для создания и уничтожения, поэтому каждый компилятор может использовать свои собственные операции new/delete (поскольку разные среды выполнения имеют свои собственные кучи).
Я попробовал следующий код, но он разбился на первом методе-члене:
интерфейс.h
#pragma once
class IRefCounted
{
public:
virtual ~IRefCounted(){}
virtual void AddRef()=0;
virtual void Release()=0;
};
class IClass : public IRefCounted
{
public:
virtual ~IClass(){}
virtual void PrintSomething()=0;
};
test.cpp, скомпилированный с помощью VC9, test.exe
#include "interface.h"
#include <iostream>
#include <windows.h>
int main()
{
HMODULE dll;
IClass* (*method)(void);
IClass *dllclass;
std::cout << "Loading a.dll\n";
dll = LoadLibraryW(L"a.dll");
method = (IClass* (*)(void))GetProcAddress(dll, "CreateClass");
dllclass = method();//works
dllclass->PrintSomething();//crash: Access violation writing location 0x00000004
dllclass->Release();
FreeLibrary(dll);
std::cout << "Done, press enter to exit." << std::endl;
std::cin.get();
return 0;
}
a.cpp, скомпилированный с помощью g++ g++.exe -shared c.cpp -o c.dll
#include "interface.h"
#include <iostream>
class A : public IClass
{
unsigned refCnt;
public:
A():refCnt(1){}
virtual ~A()
{
if(refCnt)throw "Object deleted while refCnt non-zero!";
std::cout << "Bye from A.\n";
}
virtual void AddRef()
{
++refCnt;
}
virtual void Release()
{
if(!--refCnt)
delete this;
}
virtual void PrintSomething()
{
std::cout << "Hello World from A!" << std::endl;
}
};
extern "C" __declspec(dllexport) IClass* CreateClass()
{
return new A();
}
РЕДАКТИРОВАТЬ: я добавил следующую строку в метод GCC CreateClass, текст был правильно напечатан на консоли, поэтому его вызов функции, безусловно, убивает его.
std::cout << "C.DLL Create Class" << std::endl;
Мне было интересно, как COM удается поддерживать двоичную совместимость даже между языками, поскольку в основном все его классы имеют наследование (хотя и только одно) и, следовательно, виртуальные функции. Меня не сильно беспокоит, если я не могу иметь перегруженные операторы/функции, пока я могу поддерживать базовые вещи ООП (например, классы и одиночное наследование).
=0
. - person greatwolf   schedule 13.03.2013