有没有办法使用不同的编译器构建的C++动态链接库相互兼容? 类可以拥有创建和销毁的工厂方法,因此每个编译器都可以使用自己的new/delete(因为不同的运行时有它们自己的堆)。
我尝试了以下代码,但在第一个成员方法上崩溃了:
interface.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如何在跨语言情况下保持二进制兼容性,因为它基本上是继承的类(尽管仅有单一继承)和虚函数。如果我不能有重载运算符/函数,只要我能够保持基本的面向对象编程(即类和单一继承),我就不会太担心。
=0
。 - greatwolf