C++ 如何链接C++;具有常量参数的函数,或C++;结构到可执行文件?

C++ 如何链接C++;具有常量参数的函数,或C++;结构到可执行文件?,c++,d,ld,C++,D,Ld,我试图把C++对象文件链接到D可执行文件。 dlang.org建议这应该是可能的: 实际上,为我要链接的C++对象文件创建一个D接口文件是直接的。C++模块的暴露部分只是一组全局C样式函数和一些结构。 我想做的应该是: rdmd -main -unittest -L-lcurl -Lsvm.o "-L/usr/lib/libstdc++.a" svmWrapper.d 其中SVM .O是C++对象文件,而SvMrPrAPr.d是构建到可执行文件的D文件(在这种情况下,只运行单元测试的一个文件)

我试图把C++对象文件链接到D可执行文件。 dlang.org建议这应该是可能的:

<>实际上,为我要链接的C++对象文件创建一个D接口文件是直接的。C++模块的暴露部分只是一组全局C样式函数和一些结构。 我想做的应该是:

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

其中SVM .O是C++对象文件,而SvMrPrAPr.d是构建到可执行文件的D文件(在这种情况下,只运行单元测试的一个文件)。

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

svm_交叉验证函数就是一个例子。.di文件包含:

 extern(C++) void svm_cross_validation(const(svm_problem) *prob, const(svm_parameter) *param, int nr_fold, double *target);
struct svm_node
{
        int index;
        double value;
}
<> >我相信它相当于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文件包含:

 extern(C++) void svm_cross_validation(const(svm_problem) *prob, const(svm_parameter) *param, int nr_fold, double *target);
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_节点类型的内部变量时,才会出现这些错误。仅仅实例化指向svm_节点的指针是不够的


反正,我非常感谢任何能解释我在这里哪里出错的人。

你可能被结构定义咬了一口,因为你的文件被称为
svm.di
,而不是
svm.d
,你正在使用
rdmd
进行编译,它为你隐藏了大部分细节

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

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

i、 e.您的
.o
文件包含与您在
svm.di
文件中声明的模式匹配的svm\u交叉验证的导出定义

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

<>我通常使用一个MaFe文件,因为我将多个语言和文件混合在一起。我已经建立了一个MaFIX文件,构建了相关代码,以确保C++代码在.CPP文件发生变化时编译。
谢谢!需要编译的结构对我来说很有意义。该.o文件确实包含有问题的函数(我可以从.o中的其他函数调用它,链接很好).最后,我在.cpp文件中编写了一系列包装器,这些包装器采用非常量参数,并使用常量参数调用函数。rdmd对此很满意,并且程序现在可以按预期工作,因此我假设这是一个常量没有以完全相同的方式绑定的东西。也有一个很好的makefile,但感谢您的建议尽管如此,这将对未来的读者有用。奇怪的是,常量参数对我来说没有问题(dmd v2.065)它们是否可能位于命名空间中?它们似乎不在命名空间中。C++文件最初是想通过它的头提供一个C接口,所以大多数函数都是全局的。我能想到的唯一一件事是,它们是否被封装在<代码>外部“C”中。块,该块将从结果
.o
中删除所有
C++
名称损坏,但基于您先前对nm输出中列出的全名(包括参数)的注释,情况似乎并非如此。