使我的C++库能够与C语言一起使用(减少函数集)

5

我一直想建立一个共享库,利用类来保持其功能的清晰性(它可能需要许多输入或处理),尽管我仍希望针对C平台进行目标设置。

如果我在所有原型上应用extern "C" {},并提供一组暴露的函数作为类函数的模拟,以便对象不“必须”使用我的库,那么这些普通函数能够在链接到它的C程序中工作吗?


可能是c++库与c接口的重复问题。 - CharlesB
2个回答

6
如果您按照您所描述的方式创建了一个dll,即所有接口都是extern "C",并且接口中的所有类型都是POD,则在C或.NET中使用它时几乎不会有任何问题。
示例:
class MyClass
{
 public:
    MyClass(float x) {...}
    void method(int x) {...}
    ~MyClass() {...}
};

#define MYAPI extern "C" __declspec(dllexport) //or whatever the syntax is for your compiler

MYAPI MyClass* CreateMyClass(float x)
{
    return new MyClass(x);    
}

MYAPI void MyClass_method(MyClass* p, int x)
{
   return p->method(x);
}

MYAPI void DestroyMyClass(MyClass* p )
{
   delete p;
}

4
别忘了捕获异常——异常无法跨越“extern "C"”边界。 - Larry Osterman
@Larry:谢谢,让我们把这个留给楼主吧 ;) - Armen Tsirunyan
我很欣赏这个例子,根据我所了解的有关dll表单的知识,将其移植到类Unix系统的共享对象应该也很简单。 - Alexander

3
您可能需要为您的C源文件准备单独的头文件进行包含。C头文件不应该有任何C++代码,因为C编译器可能需要解析它们。在这里,您将为您的C++库提供C接口。通过在此头文件中提供“extern"C"”修饰符,并且像您所指示的那样对函数声明进行修饰,您告诉编译器使链接适用于C程序。
因此,如果您需要C程序保持对对象的引用,请通过C接口作为“void *”指针来传递。在C中,您只需将其视为神奇的cookie即可。
其他帖子讲述了通过DLL公开接口的方法,这也是有用的知识,但严格来说并不涉及(标准)语言方面。
编辑
啊呸。 "extern"C"”部分是C++语法。因此,在C ++侧,您必须使用“extern"C"”声明C接口函数,但在C侧,您不能使用该语法。您可以通过常见的惯用语实现此操作:
#ifdef __cplusplus
extern "C" {
#endif
void foo();
#ifdef __cplusplus
}
#endif

我很感激你的建议,这看起来更像是一个有趣的挑战,而不是一项艰巨的任务。 - Alexander
1
@alexander:感谢您的反馈。祝你好运。 - gregg

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接