C ++ DLL用于C程序 [英] C++ DLL to be used in C program

查看:196
本文介绍了C ++ DLL用于C程序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个dll的源代码是用C ++编写的。我想创建该库的静态版本,我想能够将该静态库链接到另一个用纯C编写的库中。编译器是Windows上的MinGW。
我应该如何编译第一个C ++静态库,使其可以被C库使用?

解决方案

如果你计划调用C ++类的一个实例的成员函数,您将需要提供转发功能。您还需要提供至少一个函数来返回指向要访问的类的实例的指针。这有很大的原因。 1)构造函数是特殊的,并且不具有名称,因此它们不能被直接调用,2)成员函数采用隐式这个参数可以传递在堆栈中注册。例如,我们假设你有一个名为 SomeClass的类

  #include< iostream> 

class SomeClass
{
public:
void Print(int value){std :: cout <值<<的std :: ENDL; }
void Print(const char * value){std :: cout<<<值<<的std :: ENDL; }
};

现在,您要添加一种安全的方式来创建和访问该类的实例。您可以创建一个提供创建功能和转发功能的C接口。您可以先添加一个附加的头文件来为 SomeClass提供C接口


XSomeClass.h




  #ifdef __cplusplus 
externC
{
#endif

//表示SomeClass的C类型。这增加了一些类型的安全性,它用于C
typedef struct XSomeClass XSomeClass;

//这将创建一个SomeClass的实例,并返回一个指向XSomeClass的指针
XSomeClass * SomeClass_Create();

//转发访问SomeClass的成员函数。这些调用将
//显式指向XSomeClass作为第一个参数。 self指向
// SomeClass_Create()返回的SomeClass的一个实例
void SomeClass_PrintInt(XSomeClass * self,int value);
void SomeClass_PrintString(XSomeClass * self,const char * value);

#ifdef __cplusplus
}
#endif

现在你需要提供一个C接口的实现。这是所有的魔法发生,允许你从C调用C ++成员函数。


XSomeClass.cpp




  externCXSomeClass * SomeClass_Create()
{
return reinterpret_cast< XSomeClass *>(new SomeClass());


externCvoid SomeClass_PrintInt(XSomeClass * self,int value)
{
reinterpret_cast< SomeClass *>(self) - >打印(值);
}

externCvoid SomeClass_PrintString(XSomeClass * self,const char * value)
{
reinterpret_cast< SomeClass *&((self))>打印(值);
}

我建议使用 reinterpret_cast 超过C风格的演员,以防止意外删除 const 限定词。



要从C访问C ++库,您现在可以执行以下示例


main.c




  #includeXSomeClass。 h

int main(int,char **)
{
XSomeClass * sc = SomeClass_Create();
SomeClass_PrintInt(sc,1);
SomeClass_PrintString(sc,hello);
}







注意:只需将C ++库放入DLL中,并调用 GetProcAddress 为免费函数和静态成员函数很难,因为您需要考虑到名称变化


I have a dll whose source code is written in C++ . I would like to create the static version of that library and I would like to be able to link this static library in a another library which is written in pure C. The compiler is MinGW on Windows. How should I compile the first C++ static library so to make it usable by a C library?

解决方案

If you plan on calling member functions of an instance of C++ class you will need to provide forwarding functions. You will also need to provide at least one function to return a pointer to an instance of the class you want to access. There are to significant reasons for this. 1) Constructors are special and do not have names so they cannot be called directly and 2) member functions take an implicit this parameter which can be passed on the stack or in a register.

For instance let's say you have a class called SomeClass

#include <iostream>

class SomeClass
{
public:
    void Print(int value) { std::cout << value << std::endl; }
    void Print(const char *value) { std::cout << value << std::endl; }
};

Now, you want to add a type safe way of creating and accessing an instance of that class. You can create a C interface that provides the creation function and forwarding functions. You might start by adding an additional header file to provide the C interface for SomeClass

XSomeClass.h

#ifdef __cplusplus
extern "C"
{
#endif

    // C type representing SomeClass. This adds some type safety to it's use in C    
    typedef struct XSomeClass XSomeClass;

    // This will create an instance of SomeClass and return a pointer to XSomeClass
    XSomeClass* SomeClass_Create( );

    // forwarding calls to access member functions of SomeClass. These calls take
    // an explicit pointer to XSomeClass as the first parameter. self points to
    // an instance of SomeClass returned by SomeClass_Create()
    void SomeClass_PrintInt(XSomeClass* self, int value);
    void SomeClass_PrintString(XSomeClass* self, const char *value);

#ifdef __cplusplus
}
#endif

Now you need to provide an implementation of the C interface. This is where all the magic happens that allows you to call C++ member functions from C.

XSomeClass.cpp

extern "C" XSomeClass* SomeClass_Create()
{
    return reinterpret_cast<XSomeClass*>(new SomeClass());
}

extern "C" void SomeClass_PrintInt(XSomeClass* self, int value)
{
    reinterpret_cast<SomeClass*>(self)->Print(value);
}

extern "C" void SomeClass_PrintString(XSomeClass* self, const char *value)
{
    reinterpret_cast<SomeClass*>(self)->Print(value);
}

I recommend using reinterpret_cast over C style casts to prevent the accidental removal of const qualifiers.

To access the C++ library from C you can now do something like the example below

main.c

#include "XSomeClass.h"

int main(int, char**)
{
    XSomeClass *sc = SomeClass_Create();
    SomeClass_PrintInt(sc, 1);
    SomeClass_PrintString(sc, "hello");
}



Note: Simply putting the C++ library in a DLL and calling GetProcAddress for free functions and static member functions will be difficult as you will need to take into account name mangling.

这篇关于C ++ DLL用于C程序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆