如何在同一项目的C层中调用C ++函数?

问题描述

我有一个C ++标头和abc.hpp和abc.cpp之类的cpp文件,其中有2个类,分别是A类和B类,我试图编写一个C层,其中包含调用C ++层方法的不同方法,以调用我需要先创建A类的实例的C ++方法,然后使用该实例调用C ++方法。我已经创建了C层,但是尝试了不同的方法来创建B类的实例,但这是不可能的。

这是ABC.hpp

#ifndef ABC_HPP
#define ABC_HPP

namespace utils {

    using std::vector;
    using std::string;

    class  __declspec(dllexport) A
    {
        protected:
            string m_color;
            string m_type;

        public:
            A() {
                // TODO: Complete the constructor by intializing everything
                m_color = "";
                                m_type = "";
            }
            void setColor(string icolor){m_color = icolor;}
                        void setType(string itype){m_type = itype;}
                        string getColor(){return m_color;}
                        string getType() {return m_type;}   
            virtual ~A() {};
    };
    class __declspec(dllexport) B
    {
        // Member Variables
    protected:
        string file_name;
        string place_name;

    public:
       void setFilename(fname){file_name = fname;}
       void setPlaceName(pname){place_name = pname;} 
       string getFilename(){return file_name;}
       string  getplaceName() {return place_name;}
       void getRes();
       
    };
};
#endif

类似地,我们有ABC.cpp

接下来,我创建C层xyz_c.h

#ifndef XYZ_H
#define XYZ_H

#ifdef __cplusplus
extern "C"
{
#endif
    __declspec(dllexport) int getPlaceNames(char** oNames);

#ifdef __cplusplus
}
#endif
#endif

接下来,我创建XYZ.cpp

#include "XYZ.h"
#include "ABC.h"

#ifdef __cplusplus
extern "C" {
#endif
  int getResults(char** oNames)
{
    //here I need to create the instance of B to Call C++ layer getRes()
}


#ifdef __cplusplus
}
#endif

解决方法

执行此操作的正确方法如下。在“ C”接口代码中,应该具有与c ++接口匹配的函数,并添加了void *参数。此参数将用于保存实例,以供XYZ将来使用。

所以我要添加一个abc.c,其定义为:

void setFilename(void* b,char *fname){
  ((B*)b)->setFilename(fname);
};

当然,您还需要定义创建者函数,例如:

void* CreateB(){
  return (void*)new B();
}
,

您不能。 C ++旨在允许它使用已经编写的整套C旧代码,但是另一面是不可能的……仅仅是因为在设计C时没有可用的C ++,并且C没有像C ++那样的结构。才能链接用C编写的例程。

这意味着,如果要合并C和C ++代码,则该程序必须作为C ++程序链接(构建为),并且可以包含所需的每个例程(可以将单个模块编译为C模块),但是可以从C ++代码中访问它们,包括C ++代码中的extern "C"链接语句(绝不能相反)

C ++对方法和c ++函数有一个命名约定,该约定在名称中包括有关参数类型和数量的信息,以允许重载并将对象实例包括在参数列表中。这对于C编译器来说是完全未知的,因此您无法轻易猜出链接程序用于void f(void)函数这样简单的名称的名称(它可以像1f4void之类的(是的,以数字开头),使得无法从C进行访问(因为C标识符必须以字母或下划线开头)。如果将f声明为extern "C" f(void),则可以从C模块中调用它,甚至可以可以用C实现(并用c进行编译),链接器将其称为_f(或f也在今天使用,取决于编译器)

您甚至可以将int main(int argc,char **argv)函数编写为C函数,但是在链接它时,如果希望程序包含C ++代码,则需要使用C ++链接器。

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...