1

可能重复:
如何从 C 调用用 C++ 编写的库?

我正在修改pHash,我想调用该函数以从文件位置生成感知散列。当我尝试调用名为 ph_dct_imagehash 的函数时,编译器会抛出此错误:

/usr/include/CImg.h:72:18: fatal error: cstdio: No such file or directory
compilation terminated.

此时我意识到 pHash 是用 C++ 编写的,因此在 C 程序中包含 C++ 标头是行不通的。尽管如此,函数本身似乎应该可以从 C 调用,因为它的参数和返回值都没有使用 C++ 构造。有什么好方法可以从 C 调用 C++ 函数 ph_dct_imagehash?

注意:我这样做主要是为了更好地使用 C(不是 C++)。这就是我将自己限制在 C 的原因。

4

3 回答 3

5

只要您有一个未损坏的符号名称可以调用,您就可以很容易地将您的 C++ 库与您的 C 程序链接起来。您需要创建一个 C 安全的头文件或其他方式来转发声明函数名称,然后在最后将它们链接在一起(确保使用 C++ 感知链接器!)。

这是一个简单的例子:

$ cat cplusplus.cpp 
#include <string>

extern "C"
const char *cplusplusFunction(void)
{
    static std::string a = "Hello, C++";
    return a.c_str();
}
$ cat example.c 
#include <stdio.h>

const char *cplusplusFunction(void);

int main(void)
{
    printf("%s\n", cplusplusFunction());
    return 0;
}
$ c++ -c -o cplusplus.o cplusplus.cpp
$ cc -c -o example.o example.c 
$c++ -o example example.o cplusplus.o
$ ./example 
Hello, C++
于 2012-12-21T22:23:34.503 回答
2

您需要将 C++ 代码函数与 C 代码分开。

通常,这是通过拥有一个仅包含 C(非 C++)函数声明和解决问题所需的 C 数据结构的 .h 文件以及一个包含 C 到 C++ 接口函数的 C++ 文件来完成的。

您还需要使用

#ifdef __cplusplus
extern "C" {
#endif
.... your types and functions ... 
#ifdef __cplusplus
}
#endif

在您的头文件中,以确保 C++ 编译器不会“破坏”名称(在函数名称中标记参数的类型,例如函数 Blur(int x, int y) 可能被称为 _Blur_ii,其中常规C 不会在函数名称上添加这种“额外的东西”,因此 C 编译器会调用 _Blur - 当然,当您尝试链接时,链接器会显示“找不到 _Blur”。

编辑:此外,绝对 100% 确保您没有异常“泄漏”到 C 代码中。如果你这样做了,任何事情都可能发生,而且通常不是从天而降的金子,而是一些坏事...... :)

于 2012-12-21T22:28:39.950 回答
0

如果您使用 C++ 编译器(例如 g++ 而不是 gcc),您可以从 C 代码无缝调用 C++ 代码,一切都会正常工作。情况就是这样,因为除非你在做一些非常奇怪的事情,否则 C 包含在 C++ 中。

而且如果用g++编译还是不行的话,应该把文件后缀从.c改成.cc、.cpp、.cxx等。最好是.cc

于 2012-12-21T22:26:27.437 回答