如何将带有常量参数的C++函数或C++结构链接到D可执行文件

How can I link a C++ function with const parameters, or a C++ struct to a D executable?

本文关键字:C++ 函数 结构 可执行文件 链接 参数 常量      更新时间:2023-10-16

我正在尝试将C++对象文件链接到D可执行文件。

dlang.org建议这应该是可能的:http://dlang.org/cpp_interface.html

事实上,为我想要链接到的C++对象文件创建一个D接口文件是直接的。C++模块的公开部分只是一组全局C样式函数和一些结构。

我想做的应该是:

rdmd -main -unittest -L-lcurl -Lsvm.o "-L/usr/lib/libstdc++.a" svmWrapper.d

其中svm.o是C++对象文件,svmWrapper.d是构建为可执行文件的d文件(在本例中,只是一个将运行单元测试的文件(。

但是,对于在D文件中调用的C++对象文件中的某些(但不是所有(函数,链接器会喷出一个未定义的引用错误。我怀疑这些问题是由D接口文件中的不正确声明引起的,但不确定哪里出了问题。

svm_cross_validation函数就是一个例子。.di文件包含:

 extern(C++) void svm_cross_validation(const(svm_problem) *prob, const(svm_parameter) *param, int nr_fold, double *target);

我认为这相当于C++头文件中的声明:

void svm_cross_validation(const struct svm_problem *prob, const struct svm_parameter* param, int nr_fold, double *target);

但这可能不太正确。我认为consts有问题,但不确定是什么。链接器说:

undefined reference to `svm_cross_validation(svm_problem const*, svm_parameter const*, int, double*)'

我认为其他投诉是因为D想要从不存在的结构中获得某些类型的信息。这不那么紧迫,因为在最坏的情况下,我可以将有关这些结构的所有信息隐藏在C++模块中。我不明白为什么没有这些信息。.di文件包含:

struct svm_node
{
        int index;
        double value;
}

我认为它相当于C++头文件的

struct svm_node 
{
        int index;
        double value;
};

链接器生成许多错误:

undefined reference to `_D3svm8svm_node6__initZ'
undefined reference to `_D3svm8svm_node11__xopEqualsFKxS3svm8svm_nodeKxS3svm8svm_nodeZb'

我已经验证了只有在D文件中访问svm_node类型的内部变量时才会出现这些错误。仅仅实例化指向svm_node的指针是不够的。

不管怎样,我非常感谢任何能解释我在这里哪里出了问题的人。

您可能会被结构定义没有编译成必要的代码所困扰,因为您的文件名为svm.di而不是svm.d,并且您使用的是rdmd,它为您隐藏了大部分细节。

因为svm.di文件中有结构声明,所以必须对其进行编译。.di文件有点像C/C++.h文件,但略有不同。为rdmd修复此问题的最快方法是将svm.di重命名为svm.dtouch *.d,然后您的rdmd应该可以正确构建。

至于丢失的声明,您看起来肯定在svm.di文件中正确定义了它(现在应该已经将其重命名为svm.d。您需要通过运行nm svm.o | c++filt来验证它是否存在于从svm.cpp文件生成的svm.o文件中,这应该会产生类似于(除其他外(:

0000000000000010 T svm_cross_validation(svm_problem const*, svm_parameter const*, int, double*)

即,您的.o文件包含与您在svm.di文件中声明的模式匹配的svm_cross_validation的导出定义。

我建议将.cpp文件的结果输出重命名为不会与svm.d文件的潜在命名重叠的文件

我通常会在建筑中使用Makefile,因为我将多种语言和文件混合在一起。我构建了一个非常小的github项目,展示了一个Makefile构建相关代码,以确保在.cpp文件更改时编译C++代码。