有没有办法让不同编译器构建的 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;
}
用g++编译的a.cpp
g++.exe -共享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 内容(即类和单一继承),我就不会太烦恼。