【问题标题】:Properly using C++ functions from C正确使用 C 中的 C++ 函数
【发布时间】:2014-12-04 18:13:50
【问题描述】:

我今天早上一直在尝试为 OpenGL 设置一个对象加载器,并且已经取得了一些进展,但现在我陷入了让我的设置正常工作的最后一步。我的主要 OpenGL 程序是用c (shift.c) 编写的,我的对象加载器是用C++ (loader.cpp) 编写的。我还根据this SO thread 编写了两个loader.h 的链接器。

我认为我在翻译中做错了,因为到目前为止我所做的一切都没有正常工作。我的文件如下。

loader.h

#ifndef LOADER_H
#define LOADER_H

#ifdef _cplusplus
class Model_OBJ
{
  public:
    Model_OBJ();
    float* Model_OBJ::calculateNormal(float* coord1,float* coord2,float* coord3 );
    int Model_OBJ::Load(char *filename);  // Loads the model
    void Model_OBJ::Draw();         // Draws the model on the screen
    void Model_OBJ::Release();        // Release the model

    float* normals;             // Stores the normals
    float* Faces_Triangles;         // Stores the triangles
    float* vertexBuffer;          // Stores the points which make the object
    long TotalConnectedPoints;        // Stores the total number of connected verteces
    long TotalConnectedTriangles;     // Stores the total number of connected triangles

};
#endif /* __cplusplus */

#ifdef _cplusplus
extern "C" {
#endif
    struct model_obj;

    float* calculateNormal( float *coord1, float *coord2, float *coord3 );
    int Load(char* filename);
    void Release();
    void Draw();

    float* normals;             // Stores the normals
    float* Faces_Triangles;         // Stores the triangles
    float* vertexBuffer;          // Stores the points which make the object
    long TotalConnectedPoints;        // Stores the total number of connected verteces
    long TotalConnectedTriangles;     // Stores the total number of connected triangles

#ifdef _cplusplus
}
#endif

#endif /* LOADER_H */

loader.cpp

/*
 *
 * Demonstrates how to load and display an Wavefront OBJ file.
 * Using triangles and normals as static object. No texture mapping.
 * http://talkera.org/opengl/
 *
 * OBJ files must be triangulated!!!
 * Non triangulated objects wont work!
 * You can use Blender to triangulate
 *
 */

#include "loader.h"
// Rest of my includes

class Model_OBJ
{
  public:
    Model_OBJ();
    float* calculateNormal(float* coord1,float* coord2,float* coord3 );
    int Load(char *filename);  // Loads the model
    void Draw();         // Draws the model on the screen
    void Release();        // Release the model

    float* normals;             // Stores the normals
    float* Faces_Triangles;         // Stores the triangles
    float* vertexBuffer;          // Stores the points which make the object
    long TotalConnectedPoints;        // Stores the total number of connected verteces
    long TotalConnectedTriangles;     // Stores the total number of connected triangles

};

#define POINTS_PER_VERTEX 3
#define TOTAL_FLOATS_IN_TRIANGLE 9
using namespace std;

Model_OBJ::Model_OBJ(){...}

float* Model_OBJ::calculateNormal( float *coord1, float *coord2, float *coord3 ){...}  
int Model_OBJ::Load(char* filename){...}
void Model_OBJ::Release(){...}
void Model_OBJ::Draw(){...}

在我的shift.c 文件中。我一直在尝试做类似以下的事情。但还没有成功。

#include "loader.h"
// Up in variable declarions
struct model_obj *obj1;

int main()
{
  obj1.Load("file.obj");
}

【问题讨论】:

  • 有什么理由不一直选择 C++ 吗?您甚至可以保留现有的 C 代码并将文件重命名为 shift.cpp,这可能会使其正常工作。 C 不是 C++ 的确切子集,但在这种情况下,它可能会表现得好像是一样。
  • 我还注意到您需要一个移动构造函数、移动赋值和析构函数。也许还有复制构造函数,复制赋值。
  • 有什么理由不遵循该帖子中已接受答案的示例?
  • 我确实按照那个帖子中的答案,但遇到了问题。这就是我发布另一个的原因。
  • 请调查不透明类型struct model_obj;(不是Model_OBJ)的正确使用。请参阅该帖子中的struct animal; // a nice opaque type

标签: c++ c struct


【解决方案1】:

对于像您这样的 C++ 结构,该标头的 C 部分将需要进行重大更改。通常,围绕 C++ 类的 C 包装器看起来更像这样。 (另外你必须将class 更改为struct。)

#ifdef _cplusplus
extern "C" {
#endif
struct Model_OBJ;

Model_OBJ* Model_OBJ_new(void);
void Model_OBJ_delete(Model_OBJ*self); 

float* Model_OBJ_calculateNormal(Model_OBJ*self,float*coord1,float*coord2,float*coord3);
int Model_OBJ_Load(Model_OBJ*self,char*filename); // Loads the model
void Model_OBJ_Draw(Model_OBJ*self); // Draws the model on the screen

#ifdef _cplusplus
}
#endif

然后在 C++ 文件中,您还必须实现这些函数。

Model_OBJ* Model_OBJ_new(void) {return new Model_OBJ();}
void Model_OBJ_delete(Model_OBJ*self) {delete self}


float* Model_OBJ_calculateNormal(Model_OBJ*self,float*coord1,float*coord2,float*coord3)
{return self->calculateNormal(coord1,coord2,coord3);}
int Model_OBJ_Load(Model_OBJ*self,char*filename)
{return self->Load(filename);}
void Model_OBJ_Draw(Model_OBJ*self)
{return self->Draw();}

然后C代码就可以使用了:

int main() {
    Model_OBJ* obj1 = Model_OBJ_new();
    Model_OBJ_Load(obj1, "file.obj");
    Model_OBJ_delete(obj1);
}

【讨论】:

  • new_Model_OBJ() 在最后一个 sn-p 中应该是 Model_OBJ_new()
  • @JohnBollinger:谢谢。在最后一秒重命名以更加一致并错过了一个。
  • 进行这些更改后,当我编译时,loader.h 中出现错误,如下所示。 error: unknown type name ‘Model_OBJ’ void Model_OBJ_delete(Model_OBJ*self);
  • 次要:Model_OBJ* Model_OBJ_new(); 应该是 Model_OBJ* Model_OBJ_new(void); 所以 C 不认为这是 Model_OBJ* Model_OBJ_new(...);
  • @chux:好电话,我忘记了那个怪癖。
猜你喜欢
  • 2016-08-27
  • 1970-01-01
  • 2013-05-22
  • 2015-06-09
  • 2012-05-08
  • 2013-01-04
  • 1970-01-01
  • 2018-08-16
  • 1970-01-01
相关资源
最近更新 更多