我跟随Rudy Velthuis的优秀article关于在DLL中使用C ++类。一切都很好,除了我需要访问一些在C ++ DLL中没有相应工厂的类。如何在DLL中构造类的实例?有问题的类定义为
class __declspec(dllexport) exampleClass
{
public:
void foo();
};
现在没有工厂,我没有明确的实例化类的方法,但是我知道它可以完成,因为我已经看到了使这些类可用于Python的SWIG脚本(.i文件)。如果Python和SWIG可以做到,那么我假设/希望有一些方法可以在Delphi中实现它。
现在我对SWIG知之甚少,但它似乎为C ++错位名称生成某种地图?那附近哪儿好吗?看看DLL的导出,我想我可以访问函数&构造函数/析构函数由索引或直接损坏的名称,但这将是令人讨厌的;它会工作吗?即使我可以调用构造函数,我该怎么做相当于“new CClass();”在德尔福?
答案 0 :(得分:7)
swig的工作方式是: 1)它为每个类方法创建一个平面API并构建类工厂/驱逐程序函数。例如:
class C {
public :
C() {...}
int M1(int P1) {...}
}
它产生:
C* New_C();
Destroy_C(C*self);
int C_M1(C*self,int P1) {}
平面api必须在新的DLL中编译
2)它为平面api生产一个包含pascal中的平面api声明的单元 3)flat pascal api可以选择用于自动构建Pascal类,例如:
type TC = class
private
FObj : pointer;
public
constructor Create();
destructor Destroy(); override;
function m1(p1:integer: integer;
...
constructor TC.Create();
begin
inherited;
FObj := New_C();
end;
destructor TC.Destroy();
begin
Destroy_C(FObj);
inherited;
end;
function TC.M1(P1:integer) : integer;
begin
Result := C_M1(FObj, P1);
end;
答案 1 :(得分:5)
可以使用SWIG进行。至少应该是可能的。 我编写了一个针对ObjectPascal的SWIG模块,我在自己的项目中成功使用它。我已经转换了GEOS和GDAL / OGR库。 我在SWIG存储库中也有一个分支,但是我仍然需要完成构建所有测试套件的最后步骤并修复类型映射以使模块被接受。
有人想帮忙吗?
Stefano Moratto stefano.moratto@gmail.com www.csiat.it
答案 2 :(得分:5)
正确的方法是编写一个包装器DLL,为您需要的类公开工厂。
我不确定SWIG的工作原理,但任何依赖逆向工程改名的方法似乎都是一种可疑的方法。
此外,只应在C ++代码中创建C ++对象。您应该将对象创建语义留给C ++运行时。
存在COM存在的原因。准确地说,这个跨语言对象的比喻工作得很整齐。
我写了很多从Delphi,python和C#
调用的COM对象答案 3 :(得分:2)
如果python可以,它并不一定意味着任何语言都可以。
Python(或任何其他脚本语言)可能能够在完全相同的编译器和编译版本中访问C ++代码。
石蕊测试是否python代码可以访问该类,无论它是用哪个编译的(例如,一个python实现与msvc和gcc生成相同的DLL)
通常,具有错位名称的所有内容都是编译器和特定于-version的。所以唯一的方法是使用你所针对的编译器编译一个testprogram,反汇编它,找到apporiate运行时调用(对于类类型,构造函数和运行时助手)以及调用它们的方式,并使用cdecl函数模拟它或者在德尔福的asm。
像Rudy这样的方便人员可能会尽可能地清除使用pascal功能并将其呈现为看起来容易的东西,但HLL的交叉编译器兼容性是一个困难的(如果不是不可能的话)主题。