有什么方法可以使使用不同编译器构建的 c++ dll 相互兼容?这些类可以具有用于创建和销毁的工厂方法,因此每个编译器都可以使用自己的 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;
};
用VC9编译的test.cpp,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 是如何设法保持跨语言的二进制兼容性的,因为它基本上所有类都具有继承(尽管只有单个),因此是虚函数。只要我可以维护基本的 OOP 内容(即类和单一继承),如果我不能重载运算符/函数,我就不会感到非常困扰。